﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
using X360.IO;
using X360.STFS;
//Yeah, I don't need most of these. So sue me.
using Microsoft.VisualBasic;
using System.Net;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Diagnostics;
//using System.Collections.Specialized;


namespace WillowTree
{
    public partial class WillowTreeMain : Form
    {
        #region <<<<< LOCAL VARIABLES >>>>>

        string VersionFromServer;
        string DownloadURLFromServer;
  
        public static string AppPath = WillowSaveGame.AppPath;
        public static string DataPath = WillowSaveGame.DataPath;
        public static string XmlPath = DataPath + "Xml" + Path.DirectorySeparatorChar;

        public static string strPartName = "PartName";
        public static string strPartNumber = "PartNumeric";
        public static string strManufacturer = "Manufacturer";

        private XmlFile TitlesXml = new XmlFile(DataPath + "Titles.ini");

        List<string> WeaponNames = new List<string>();
        string NameWeapon;
        List<string> ItemNames = new List<string>();
        string NameItem;

        WillowSaveGame CurrentWSG;
        string OpenedLocker;

        #endregion

        #region <<<<< DATABASE FUNCTIONS >>>>>

        // 0 references - Build composite string by combining the attribute from each part in a thing with a space between
        private static string GetThingAttributeComposite(XmlFile xml, string[,] ThingArray, int ThingIndex, int ThingPartCount, string AttributeName)
        {
            string Name = "";
            for (int build = 0; build < ThingPartCount; build++)
            {

                string readValue = xml.XmlReadValue(ThingArray[ThingIndex, build], AttributeName);

                if (Name == "" && readValue != null)
                    Name = readValue;
                else if (readValue != null && readValue != "")
                    Name = (Name + " " + readValue);
            }

            return Name;
        }

        // 4 references references - Fetch a single element string from an Xml section
        private static string GetXmlElement(XmlFile xml, string Section, string ElementName)
        {
            string Name = xml.XmlReadValue(Section, ElementName);
            return Name;
        }

        // 0 references - Return the full name of a thing inside a list of things
        private static string GetThingName(XmlFile xml, List<List<string>> ThingList, int ThingIndex, int ThingPartCount, string ThingType)
        {
            if (ThingType == "Weapon")
                return GetWeaponNameAdvanced(ThingList[ThingIndex]);
            else if (ThingType == "Item")
                return GetItemNameAdvanced(ThingList[ThingIndex]);
            else
                throw new ArgumentException("Unknown thing type specified in GetThingName");
        }

        // 4 references - Compose the full name of a weapon from its parts (array version)
        private static string GetWeaponNameAdvanced(string[] parts)
        {
            string Name = GetPartName(parts[13]);
            string Prefix = GetPartName(parts[12]);

            string MfgText = GetPartAttribute(parts[1], "Manufacturer"); // Mfg Name
            if (MfgText == "")
                MfgText = "Generic";

            string BodyText = GetPartName(parts[3]); // Body text
            string MaterialText = GetPartName(parts[11]); // Material text

            int Model = GetPartNumber(parts[8]);        // Number from stock
            Model += GetPartNumber(parts[5]);           // Number from mag
            if ((GetPartRarity(parts[8]) == 0) || (GetPartRarity(parts[5]) == 0))
                Model = Model / 10;
            string ModelText = (Model != 0 ? Model.ToString() : "");

            string ModelName = BodyText + ModelText + MaterialText;

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (MfgText != "")
            {
                sb.Append(MfgText);
                sb.Append(' ');
            }

            if (ModelName != "")
            {
                sb.Append(ModelName);
                sb.Append(' ');
            }

            if (Prefix != "")
            {
                sb.Append(Prefix);
                sb.Append(' ');
            }

            sb.Append(Name);

            return sb.ToString();
        }
        // 9 references - Compose the full name of a weapon from its parts (list version)
        private static string GetWeaponNameAdvanced(List<string> parts)
        {
            string Name = GetPartName(parts[13]);
            string Prefix = GetPartName(parts[12]);

            string MfgText = GetPartAttribute(parts[1], "Manufacturer"); // Mfg Name
            if (MfgText == "")
                MfgText = "Generic";

            string BodyText = GetPartName(parts[3]); // Body text
            string MaterialText = GetPartName(parts[11]); // Material text

            int Model = GetPartNumber(parts[8]);        // Number from stock
            Model += GetPartNumber(parts[5]);           // Number from mag
            if ((GetPartRarity(parts[8]) == 0) || (GetPartRarity(parts[5]) == 0))
                Model = Model / 10;
            string ModelText = (Model != 0 ? Model.ToString() : "");

            string ModelName = BodyText + ModelText + MaterialText;

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (MfgText != "")
            {
                sb.Append(MfgText);
                sb.Append(' ');
            }

            if (ModelName != "")
            {
                sb.Append(ModelName);
                sb.Append(' ');
            }

            if (Prefix != "")
            {
                sb.Append(Prefix);
                sb.Append(' ');
            }

            sb.Append(Name);

            return sb.ToString();
        }

        // 2 references - Compose the full name of an item from its parts (array vesion)
        private static string GetItemNameAdvanced(string[] parts)
        {
            string Name = GetPartName(parts[8]);
            string Prefix = GetPartName(parts[7]);

            string MfgText = GetPartAttribute(parts[6], "Manufacturer"); // Mfg Name
            if (MfgText == "")
                MfgText = GetPartAttribute(parts[1], "NoManufacturerName");

            string BodyText = GetPartName(parts[5]); // Right text
            string MaterialText = GetPartName(parts[2]); // Material text

            int Model = GetPartNumber(parts[3]);        // ModelNumber text
            Model += GetPartNumber(parts[4]);           //
            if ((GetPartRarity(parts[3]) == 0) || (GetPartRarity(parts[4]) == 0))
                Model = Model / 10;
            string ModelText = (Model != 0 ? Model.ToString() : "");

            string ModelName = BodyText + ModelText + MaterialText;

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (MfgText != "")
            {
                sb.Append(MfgText);
                sb.Append(' ');
            }

            if (ModelName != "")
            {
                sb.Append(ModelName);
                sb.Append(' ');
            }

            if (Prefix != "")
            {
                sb.Append(Prefix);
                sb.Append(' ');
            }

            sb.Append(Name);

            return sb.ToString();
        }
        // 10 references - Compose the full name of an item from its parts (list vesion)
        private static string GetItemNameAdvanced(List<string> parts)
        {
            string Name = GetPartName(parts[8]);
            string Prefix = GetPartName(parts[7]);

            string MfgText = GetPartAttribute(parts[6], "Manufacturer"); // Mfg Name
            if (MfgText == "")
                MfgText = GetPartAttribute(parts[1], "NoManufacturerName");

            string BodyText = GetPartName(parts[5]); // Right text
            string MaterialText = GetPartName(parts[2]); // Material text

            int Model = GetPartNumber(parts[3]);        // ModelNumber text
            Model += GetPartNumber(parts[4]);           //
            if ((GetPartRarity(parts[3]) == 0) || (GetPartRarity(parts[4]) == 0))
                Model = Model / 10;
            string ModelText = (Model != 0 ? Model.ToString() : "");

            string ModelName = BodyText + ModelText + MaterialText;

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (MfgText != "")
            {
                sb.Append(MfgText);
                sb.Append(' ');
            }

            if (ModelName != "")
            {
                sb.Append(ModelName);
                sb.Append(' ');
            }

            if (Prefix != "")
            {
                sb.Append(Prefix);
                sb.Append(' ');
            }

            sb.Append(Name);

            return sb.ToString();
        }

        // 7 references - Fetch a given attribute from a part
        private static string GetPartAttribute(string part, string AttributeName)
        {
            string Database = part.Before('.');
            if (Database == "")
                return "";

            string PartName = part.After('.');

            string DbFileName = XmlPath + Database + ".xml";
            if (!File.Exists(DbFileName))
                return "";

            XmlFile DataFile = new XmlFile(DbFileName);

            string ComponentText = DataFile.XmlReadValue(PartName, AttributeName);
            return ComponentText;
        }

        // 9 references - Fetch the PartName attribute of a part
        private static string GetPartName(string part)
        {
            return GetPartAttribute(part, "PartName");
        }

        // 5 references - Fetch the PartNumeric attribute of a part
        private static int GetPartNumber(string part)
        {
            string ComponentText = GetPartAttribute(part, "PartNumeric");
            try
            {
                return Convert.ToInt32(ComponentText);
            }
            catch { return 0; }
        }

        // 5 references - Translate the Rarity attribute of a part and return its value
        private static int GetPartRarity(string part)
        {
            string RarityText = GetPartAttribute(part, "Rarity");
            switch (RarityText)
            {   // The rarity values are extracted directly from code contributed by CK Y
                // I assume they are correct, but I haven't tested them independently. (matt911)
                case (""):
                case ("WeaponPartRarity1_Common"):
                    return 0;
                case ("WeaponPartRarity2_Uncommon"):
                    return 1;
                case ("WeaponPartRarity3_Uncommoner"):
                    return 3;
                case ("WeaponPartRarity4_Rare"):
                    return 5;
                case ("WeaponPartRarity5_VeryRare"):
                    return 8;
                case ("WeaponPartRarity6_Legendary"):
                    return 50;
                default:
                    MessageBox.Show("Unrecognized rarity string in " + part);
                    return 0;
            }
        }

        #endregion
        #region <<<<< TREE AND LIST FUNCTIONS >>>>>

        // Functions to populate TreeViews
        public void DoQuestTree()
        {
            QuestTree.Nodes.Clear();
            XmlFile Quests = new XmlFile(DataPath + "Quests.ini");
            TreeNode PT1 = new TreeNode();
            PT1.Text = "Playthrough 1 Quests";
            PT1.Name = "PT1";
            TreeNode PT2 = new TreeNode();
            PT2.Text = "Playthrough 2 Quests";
            PT2.Name = "PT2";
            QuestTree.Nodes.Add(PT1);
            QuestTree.Nodes.Add(PT2);
            for (int build = 0; build < CurrentWSG.TotalPT1Quests; build++)
            {
                TreeNode TempNode = new TreeNode();
                TempNode.Name = "PT1";
                TempNode.Text = GetXmlElement(Quests, CurrentWSG.PT1Strings[build], "MissionName");
                if (TempNode.Text == "") TempNode.Text = "Unknown Quest";
                PT1.Nodes.Add(TempNode);


                //for(int sub_build = 0; sub_build < (CurrentWSG.PT1Values[build,3] + 4); sub_build++)
                //{
                //    TreeNode Sub = new TreeNode();
                //    Sub.Text = "Value: " + CurrentWSG.PT1Values[build, sub_build];
                //    TempNode.Nodes.Add(Sub);
                //     + CurrentWSG.TotalPT1Quests
                //}
            }

            for (int build2 = 0; build2 < CurrentWSG.TotalPT2Quests; build2++)
            {
                TreeNode TempNode = new TreeNode();
                TempNode.Name = "PT2";
                TempNode.Text = GetXmlElement(Quests, CurrentWSG.PT2Strings[build2], "MissionName");
                if (TempNode.Text == "") TempNode.Text = "Unknown Quest";

                PT2.Nodes.Add(TempNode);


                //for(int sub_build = 0; sub_build < (CurrentWSG.PT1Values[build,3] + 4); sub_build++)
                //{
                //    TreeNode Sub = new TreeNode();
                //    Sub.Text = "Value: " + CurrentWSG.PT1Values[build, sub_build];
                //    TempNode.Nodes.Add(Sub);
                //    
                //}
            }

        }
        public void DoLocationTree()
        {
            XmlFile LocationsXml = new XmlFile(DataPath + "Locations.ini");
            LocationTree.Nodes.Clear();

            for (int build = 0; build < CurrentWSG.TotalLocations; build++)
            {
                //string name = PartList.IniReadValue(CurrentWSG.LocationStrings[build], "OutpostDisplayName");
                string name = LocationsXml.XmlReadValue(CurrentWSG.LocationStrings[build], "OutpostDisplayName");
                string TempNode;
                if (name != "")
                    TempNode = name;
                else TempNode = CurrentWSG.LocationStrings[build];

                LocationTree.Nodes.Add(TempNode);
            }
            LocationTree.Update();
        }
        public void DoSkillTree()
        {
            List<string> filestoconvert = new List<string>();
            filestoconvert.Add(DataPath + "gd_skills_common.txt");
            filestoconvert.Add(DataPath + "gd_Skills2_Roland.txt");
            filestoconvert.Add(DataPath + "gd_Skills2_Lilith.txt");
            filestoconvert.Add(DataPath + "gd_skills2_Mordecai.txt");
            filestoconvert.Add(DataPath + "gd_Skills2_Brick.txt");

            XmlFile AllSkills = new XmlFile(filestoconvert, XmlPath + "gd_skills.xml");

            /*
                        XmlFile Common = new XmlFile();
                        Common.XmlFilename(DataPath + "gd_skills_common.txt");
                        XmlFile Roland = new XmlFile();
                        Roland.XmlFilename(DataPath + "gd_Skills2_Roland.txt");
                        XmlFile Lilith = new XmlFile();
                        Lilith.XmlFilename(DataPath + "gd_Skills2_Lilith.txt");
                        XmlFile Mordecai = new XmlFile();
                        Mordecai.XmlFilename(DataPath + "gd_skills2_Mordecai.txt");
                        XmlFile Brick = new XmlFile();
                        Brick.XmlFilename(DataPath + "gd_Skills2_Brick.txt");
            */
            //Ini.IniFile Common = new Ini.IniFile(DataPath + "gd_skills_common.txt");
            //Ini.IniFile Roland = new Ini.IniFile(DataPath + "gd_Skills2_Roland.txt");
            //Ini.IniFile Lilith = new Ini.IniFile(DataPath + "gd_Skills2_Lilith.txt");
            //Ini.IniFile Mordecai = new Ini.IniFile(DataPath + "gd_skills2_Mordecai.txt");
            //Ini.IniFile Brick = new Ini.IniFile(DataPath + "gd_Skills2_Brick.txt");
            SkillTree.Nodes.Clear();
            SkillLevel.Value = 0;
            SkillExp.Value = 0;
            SkillActive.SelectedItem = "No";
            for (int build = 0; build < CurrentWSG.NumberOfSkills; build++)
            {
                TreeNode TempNode = new TreeNode();
                if (AllSkills.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName") != "")
                    TempNode.Text = AllSkills.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName");
                else
                    TempNode.Text = CurrentWSG.SkillNames[build];


                /*                if (Common.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName") != "")
                                    TempNode.Text = Common.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName");
                                else if (Roland.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName") != "")
                                    TempNode.Text = Roland.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName");
                                else if (Lilith.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName") != "")
                                    TempNode.Text = Lilith.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName");
                                else if (Mordecai.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName") != "")
                                    TempNode.Text = Mordecai.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName");
                                else if (Brick.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName") != "")
                                    TempNode.Text = Brick.XmlReadValue(CurrentWSG.SkillNames[build], "SkillName");
                                else
                                    TempNode.Text = CurrentWSG.SkillNames[build];
                */
                SkillTree.Nodes.Add(TempNode);


            }



        }
        public void DoEchoTree()
        {
            EchoTree.Nodes.Clear();
            //Ini.IniFile Echos = new Ini.IniFile(DataPath + "Echos.ini");
            XmlFile Echos = new XmlFile(DataPath + "Echos.ini");
            TreeNode PT1 = new TreeNode();
            PT1.Text = "Playthrough 1 Echo Logs";
            TreeNode PT2 = new TreeNode();
            PT2.Text = "Playthrough 2 Echo Logs";
            EchoTree.Nodes.Add(PT1);
            EchoTree.Nodes.Add(PT2);
            for (int build = 0; build < CurrentWSG.NumberOfEchos; build++)
            {
                TreeNode TempNode = new TreeNode();
                TempNode.Name = "PT1";
                TempNode.Text = GetXmlElement(Echos, CurrentWSG.EchoStrings[build], "Subject");
                if (TempNode.Text == "") TempNode.Text = "Unknown Echo";
                PT1.Nodes.Add(TempNode);
            }
            if (CurrentWSG.NumberOfEchosPT2 > 0 && CurrentWSG.TotalPT2Quests > 1 && CurrentWSG.NumberOfEchosPT2 < 300)
                for (int build2 = 0; build2 < CurrentWSG.NumberOfEchosPT2; build2++)
                {
                    TreeNode TempNode = new TreeNode();
                    TempNode.Name = "PT2";
                    TempNode.Text = GetXmlElement(Echos, CurrentWSG.EchoStringsPT2[build2], "Subject");
                    if (TempNode.Text == "") TempNode.Text = "Unknown Echo";

                    PT2.Nodes.Add(TempNode);
                }
        }
        public void DoAmmoTree()
        {
            AmmoTree.Nodes.Clear();

            for (int build = 0; build < CurrentWSG.NumberOfPools; build++)
            {
                TreeNode TempNode = new TreeNode();

                TempNode.Text = GetAmmoName(CurrentWSG.ResourcePools[build]);

                AmmoTree.Nodes.Add(TempNode);

            }



        }
        public void DoWeaponTree()
        {
            WeaponTree.Nodes.Clear();

            for (int build = 0; build < CurrentWSG.WeaponStrings.Count; build++)
            {
                TreeNode TempNode = new TreeNode();
                TempNode.Text = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[build]);
                if (TempNode.Text == "") TempNode.Text = "Unknown Weapon";

                WeaponTree.Nodes.Add(TempNode);
            }

        }
        public void DoItemTree()
        {
            ItemTree.Nodes.Clear();
            //Ini.IniFile Titles = new Ini.IniFile(DataPath + "Titles.ini");
            //TitlesXml.XmlFilename(DataPath + "Titles.ini");

            for (int build = 0; build < CurrentWSG.NumberOfItems; build++)
            {
                TreeNode TempNode = new TreeNode();
                TempNode.Text = GetItemNameAdvanced(CurrentWSG.ItemStrings[build]);
                //TempNode.Name = "" + build;
                //for (int search_name = 0; search_name < 9; search_name++)
                //{

                //TreeNode Sub = new TreeNode();
                //Sub.Text = "Part " + (search_name + 1) + ": " + CurrentWSG.ItemStrings[build][search_name];
                //TempNode.Nodes.Add(Sub);

                // if (TempNode.Text == "" && Titles.IniReadValue(CurrentWSG.ItemStrings[build][search_name], "PartName") != null)
                //     TempNode.Text = (Titles.IniReadValue(CurrentWSG.ItemStrings[build][search_name], "PartName"));
                // else if (Titles.IniReadValue(CurrentWSG.ItemStrings[build][search_name], "PartName") != null)
                //     TempNode.Text = (TempNode.Text + " " + Titles.IniReadValue(CurrentWSG.ItemStrings[build][search_name], "PartName"));

                // }
                if (TempNode.Text == "") TempNode.Text = "Unknown Item";
                //TreeNode Sub_Ammo = new TreeNode();
                //TreeNode Sub_Quality = new TreeNode();
                //TreeNode Sub_Slot = new TreeNode();
                //Sub_Ammo.Text = "Quantity: " + CurrentWSG.ItemValues[build][0];
                //Sub_Quality.Text = "Quality Level: " + CurrentWSG.ItemValues[build][1];
                //Sub_Slot.Text = "Equipped: " + CurrentWSG.ItemValues[build][2];
                //TempNode.Nodes.Add(Sub_Ammo);
                //TempNode.Nodes.Add(Sub_Quality);
                //TempNode.Nodes.Add(Sub_Slot);
                ItemTree.Nodes.Add(TempNode);
            }

        }
        public void DoLockerTree(string InputFile)
        {
            LockerTree.Nodes.Clear();

            OpenedLocker = InputFile;
            XmlLocker.path = InputFile;

            // Assumed that the List contains no dupes

            foreach (string iniListSectionName in XmlLocker.stListSectionNames())
            {
                TreeNode temp = new TreeNode();
                temp.Text = iniListSectionName;
                temp.Name = iniListSectionName;
                LockerTree.Nodes.Add(temp);
            }
        }
        // Used to convert wtl -> xml locker
        public void DoLockerTreetry(string InputFile)
        {
            LockerTreetry2.Nodes.Clear();

            // rootnode
            TreeNode ndroot = new TreeNode();
            ndroot.Text = "INI";
            ndroot.Expand();
            LockerTreetry2.Nodes.Add(ndroot);

            TreeNode[] ndparts = new TreeNode[19];
            string[] strParts = new string[19];
            int[] ndcntparts = new int[19];


            bool bFound;

            //Build tree

            // read file (default.wtl) to stringarray
            string[] strRead = new string[19];
            string line;
            int count = 0;

            // Read the file and display it line by line.
            System.IO.StreamReader file = new System.IO.StreamReader(InputFile);
            while ((line = file.ReadLine()) != null)
            {
                // Section
                if (line.Length > 0) // no empty lines
                {
                    if (line.StartsWith("[") && line.EndsWith("]"))
                    {
                        strRead[15] = line.Substring(1, line.Length - 2);
                        if (strRead[15].Contains(" (Copy"))
                            strRead[15] = strRead[15].Remove(strRead[15].IndexOf(" (Copy"));

                        count = 0;
                    }
                    if (line.Contains("Type="))
                    {
                        strRead[0] = line.Substring(line.IndexOf("=") + 1);
                        count++;
                    }
                    if (line.Contains("Rating="))
                    {
                        strRead[16] = line.Substring(line.IndexOf("=") + 1);
                        count++;
                    }
                    if (line.Contains("Description="))
                    {
                        strRead[17] = line.Substring(line.IndexOf("=") + 1);
                        count++;
                    }
                    for (int partindex = 1; partindex < 15; partindex++)
                    {
                        if (line.Contains("Part" + partindex + "="))
                        {
                            strRead[partindex] = line.Substring(line.IndexOf("=") + 1);
                            count++;
                        }
                    }

                    if (count == 17)
                    {
                        count = 0;
                        for (int partindex = 0; partindex < 1; partindex++)
                        {
                            // All sections
                            // read the ini values
                            bFound = false;
                            ndparts[partindex] = null;
                            strParts[partindex] = null;

                            //read type
                            strParts[partindex] = strRead[partindex];

                            for (int ndcnt = 0; ndcnt < ndroot.Nodes.Count; ndcnt++)
                            {
                                if (ndroot.Nodes[ndcnt].Text == strParts[partindex])
                                {
                                    bFound = true;
                                    ndparts[partindex] = ndroot.Nodes[ndcnt];
                                    break;
                                }
                            }
                            if (!bFound)
                            {
                                ndparts[partindex] = new TreeNode();
                                ndparts[partindex].Text = strParts[partindex];
                                ndparts[partindex].Expand();
                                ndroot.Nodes.Add(ndparts[partindex]);
                            }

                        }

                        for (int partindex = 1; partindex < 18; partindex++)
                        {
                            // All sections
                            // read the ini values
                            bFound = false;
                            ndparts[partindex] = null;
                            strParts[partindex] = null;

                            //read
                            strParts[partindex] = strRead[partindex];

                            for (int ndcnt = 0; ndcnt < ndparts[partindex - 1].Nodes.Count; ndcnt++)
                            {
                                if (ndparts[partindex - 1].Nodes[ndcnt].Text == strParts[partindex])
                                {
                                    bFound = true;
                                    ndparts[partindex] = ndparts[partindex - 1].Nodes[ndcnt];
                                    break;
                                }
                            }
                            if (!bFound)
                            {
                                ndparts[partindex] = new TreeNode();
                                ndparts[partindex].Text = strParts[partindex];
                                ndparts[partindex].Expand();
                                ndparts[partindex - 1].Nodes.Add(ndparts[partindex]);
                            }
                        }
                    }
                }
            }
            file.Close();

            List<string> listNames = new List<string>();

            XmlTextWriter writer = new XmlTextWriter(InputFile.Replace(".wtl", ".xml"), new System.Text.ASCIIEncoding());
            writer.Formatting = Formatting.Indented;
            writer.Indentation = 2;
            writer.WriteStartDocument();
            writer.WriteComment("Comment");
            writer.WriteStartElement("INI");

            for (int ndcntrt = 0; ndcntrt < ndroot.Nodes.Count; ndcntrt++)
            {
                TreeNode ndtype = ndroot.Nodes[ndcntrt];
                for (int ndcnttype = 0; ndcnttype < ndtype.Nodes.Count; ndcnttype++)
                {
                    TreeNode ndpart1 = ndtype.Nodes[ndcnttype];

                    for (int ndcntpart1 = 0; ndcntpart1 < ndpart1.Nodes.Count; ndcntpart1++)
                    {
                        TreeNode ndpart2 = ndpart1.Nodes[ndcntpart1];

                        for (int ndcntpart2 = 0; ndcntpart2 < ndpart2.Nodes.Count; ndcntpart2++)
                        {
                            TreeNode ndpart3 = ndpart2.Nodes[ndcntpart2];
                            for (int ndcntpart3 = 0; ndcntpart3 < ndpart3.Nodes.Count; ndcntpart3++)
                            {
                                TreeNode ndpart4 = ndpart3.Nodes[ndcntpart3];

                                for (int ndcntpart4 = 0; ndcntpart4 < ndpart4.Nodes.Count; ndcntpart4++)
                                {
                                    TreeNode ndpart5 = ndpart4.Nodes[ndcntpart4];

                                    for (int ndcntpart5 = 0; ndcntpart5 < ndpart5.Nodes.Count; ndcntpart5++)
                                    {
                                        TreeNode ndpart6 = ndpart5.Nodes[ndcntpart5];

                                        for (int ndcntpart6 = 0; ndcntpart6 < ndpart6.Nodes.Count; ndcntpart6++)
                                        {
                                            TreeNode ndpart7 = ndpart6.Nodes[ndcntpart6];

                                            for (int ndcntpart7 = 0; ndcntpart7 < ndpart7.Nodes.Count; ndcntpart7++)
                                            {
                                                TreeNode ndpart8 = ndpart7.Nodes[ndcntpart7];

                                                for (int ndcntpart8 = 0; ndcntpart8 < ndpart8.Nodes.Count; ndcntpart8++)
                                                {
                                                    TreeNode ndpart9 = ndpart8.Nodes[ndcntpart8];

                                                    for (int ndcntpart9 = 0; ndcntpart9 < ndpart9.Nodes.Count; ndcntpart9++)
                                                    {
                                                        TreeNode ndpart10 = ndpart9.Nodes[ndcntpart9];

                                                        for (int ndcntpart10 = 0; ndcntpart10 < ndpart10.Nodes.Count; ndcntpart10++)
                                                        {
                                                            TreeNode ndpart11 = ndpart10.Nodes[ndcntpart10];

                                                            for (int ndcntpart11 = 0; ndcntpart11 < ndpart11.Nodes.Count; ndcntpart11++)
                                                            {
                                                                TreeNode ndpart12 = ndpart11.Nodes[ndcntpart11];

                                                                for (int ndcntpart12 = 0; ndcntpart12 < ndpart12.Nodes.Count; ndcntpart12++)
                                                                {
                                                                    TreeNode ndpart13 = ndpart12.Nodes[ndcntpart12];

                                                                    for (int ndcntpart13 = 0; ndcntpart13 < ndpart13.Nodes.Count; ndcntpart13++)
                                                                    {
                                                                        TreeNode ndpart14 = ndpart13.Nodes[ndcntpart13];
                                                                        TreeNode ndpart15 = ndpart14.Nodes[0];
                                                                        TreeNode ndpart16 = ndpart15.Nodes[0];
                                                                        TreeNode ndpart17 = ndpart16.Nodes[0];

                                                                        string NewName = "";

                                                                        if (listNames.Contains(ndpart15.Text))
                                                                        {
                                                                            int nCount = 1;
                                                                            while (listNames.Contains(ndpart15.Text + " (Copy " + nCount + ")"))
                                                                                nCount++;

                                                                            NewName = ndpart15.Text + " (Copy " + nCount + ")";
                                                                        }
                                                                        else
                                                                        {
                                                                            NewName = ndpart15.Text;
                                                                        }
                                                                        listNames.Add(NewName);

                                                                        writer.WriteStartElement("Section");
                                                                        writer.WriteElementString("Name", NewName);
                                                                        writer.WriteElementString("Type", ndtype.Text);
                                                                        writer.WriteElementString("Rating", ndpart16.Text);
                                                                        writer.WriteElementString("Description", ndpart17.Text);

                                                                        writer.WriteElementString("Part1", ndpart1.Text);
                                                                        writer.WriteElementString("Part2", ndpart2.Text);
                                                                        writer.WriteElementString("Part3", ndpart3.Text);
                                                                        writer.WriteElementString("Part4", ndpart4.Text);
                                                                        writer.WriteElementString("Part5", ndpart5.Text);
                                                                        writer.WriteElementString("Part6", ndpart6.Text);
                                                                        writer.WriteElementString("Part7", ndpart7.Text);
                                                                        writer.WriteElementString("Part8", ndpart8.Text);
                                                                        writer.WriteElementString("Part9", ndpart9.Text);
                                                                        writer.WriteElementString("Part10", ndpart10.Text);
                                                                        writer.WriteElementString("Part11", ndpart11.Text);
                                                                        writer.WriteElementString("Part12", ndpart12.Text);
                                                                        writer.WriteElementString("Part13", ndpart13.Text);
                                                                        writer.WriteElementString("Part14", ndpart14.Text);
                                                                        // Hardcoded values, the wtl has no values for that
                                                                        writer.WriteElementString("RemAmmo_Quantity", "0");
                                                                        writer.WriteElementString("Quality", "5");
                                                                        writer.WriteElementString("Level", "63");
                                                                        writer.WriteEndElement();
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
            writer.Close();
        }
        // Clear out weapon/itemdupes by splitting them to their parts and add all to a tree
        // Clear out namedupes too (renaming to (Copy x)
        public void DoLockerTreeNodupe(string InputFile)
        {
            LockerTreetry2.Nodes.Clear();

            // rootnode
            TreeNode ndroot = new TreeNode();
            ndroot.Text = "INI";
            ndroot.Expand();
            LockerTreetry2.Nodes.Add(ndroot);

            XmlDocument xmlrdrdoc = new XmlDocument();
            
            xmlrdrdoc.Load(InputFile);

            // get a list of all items
            XmlNodeList xnrdrList = xmlrdrdoc.SelectNodes("/INI/Section");
            foreach (XmlNode xn in xnrdrList)
            {
                //xn.Value
                //temp = xn.InnerText.ToString();
                //Console.WriteLine(xn.InnerText);
                TreeNode ndparent = ndroot;
                TreeNode ndchild = null;
                bool bFound;

                string[] strParts = new string[]
                {
                    xn["Type"].InnerText,
                    xn["Part1"].InnerText,
                    xn["Part2"].InnerText,
                    xn["Part3"].InnerText,
                    xn["Part4"].InnerText,
                    xn["Part5"].InnerText,
                    xn["Part6"].InnerText,
                    xn["Part7"].InnerText,
                    xn["Part8"].InnerText,
                    xn["Part9"].InnerText,
                    xn["Part10"].InnerText,
                    xn["Part11"].InnerText,
                    xn["Part12"].InnerText,
                    xn["Part13"].InnerText,
                    xn["Part14"].InnerText,
                    xn["Name"].InnerText,
                    xn["Rating"].InnerText,
                    xn["Description"].InnerText,
                    //"0", "5", "63" 
                    xn["RemAmmo_Quantity"].InnerText,
                    xn["Quality"].InnerText,
                    xn["Level"].InnerText
                };
                //xn.Attributes["Name"].Value };

                if (strParts[15].Contains(" (Copy"))
                    strParts[15] = strParts[15].Remove(strParts[15].IndexOf(" (Copy"));
                /*
                string itemtypeprefixget = "";
                string itemtypeprefixgetsc = "";
                if (strParts[0] == "Item")
                {
                    //Type in Part2 -> strParts[2]
                    itemtypeprefixget = GetAttribute(TitlesXml, strParts[2], "Prefix");
                    if (itemtypeprefixget.Length == 0)
                    {
                        // Create a Section with the default prefix
                        string itemtypeprefix = strParts[2].Substring(strParts[2].LastIndexOf(".") + 1);
                        itemtypeprefix = itemtypeprefix.Substring(itemtypeprefix.IndexOf("_") + 1);
                        TitlesXml.XmlWriteValue(strParts[2], "Prefix", itemtypeprefix);
                        itemtypeprefixget = itemtypeprefix;
                    }
                    itemtypeprefixget += " "; // Add trailing space

                    if (!strParts[15].StartsWith(itemtypeprefixget + itemtypeprefixgetsc) && itemtypeprefixget.Length > 1)
                    {
                        strParts[15] = itemtypeprefixget + itemtypeprefixgetsc + GetAttribute(TitlesXml, strParts[8], "PartName");
                        if (strParts[15].EndsWith(" "))
                            strParts[15] = strParts[15] + GetAttribute(TitlesXml, strParts[9], "PartName");
                        else
                            strParts[15] = strParts[15] + ' ' + GetAttribute(TitlesXml, strParts[9], "PartName");
                    }
                }
                else if (strParts[0] == "Weapon")
                {
                    //Type in Part1 -> strParts[1]
                    itemtypeprefixget = GetAttribute(TitlesXml, strParts[1], "Prefix");
                    if (itemtypeprefixget.Length == 0)
                    {
                        string itemtypeprefix = strParts[1].Substring(strParts[1].LastIndexOf(".") + 1);
                        itemtypeprefix = itemtypeprefix.Substring(itemtypeprefix.IndexOf("_") + 1);
                        if (itemtypeprefix.StartsWith("Weapon_"))
                            itemtypeprefix = itemtypeprefix.Substring(7);

                        TitlesXml.XmlWriteValue(strParts[1], "Prefix", itemtypeprefix);
                        itemtypeprefixget = itemtypeprefix;
                    }
                    itemtypeprefixget += " "; // Add trailing space

                    if (strParts[1].EndsWith("Scorpio"))
                    {
                        // if its a scorpio better take the type in Part3 -> strParts[3]
                        //gd_weap_assault_shotgun.A_Weapon.WeaponType_assault_shotgun
                        itemtypeprefixgetsc = GetAttribute(TitlesXml, strParts[3], "ScorpioPrefix");
                        if (itemtypeprefixgetsc.Length == 0)
                        {
                            string itemtypeprefixsc = strParts[3].Substring(strParts[3].LastIndexOf(".") + 1);
                            itemtypeprefixsc = itemtypeprefixsc.Substring(itemtypeprefixsc.IndexOf("_") + 1);
                            if (itemtypeprefixsc.StartsWith("Weapon_"))
                                itemtypeprefixsc = itemtypeprefixsc.Substring(7);

                            TitlesXml.XmlWriteValue(strParts[3], "ScorpioPrefix", itemtypeprefixsc);
                            itemtypeprefixgetsc = itemtypeprefixsc;


                        }
                        itemtypeprefixgetsc += " "; // Add trailing space
                    }

                    if (!strParts[15].StartsWith(itemtypeprefixget + itemtypeprefixgetsc) && itemtypeprefixget.Length > 1)
                    {
                        strParts[15] = itemtypeprefixget + itemtypeprefixgetsc + GetAttribute(TitlesXml, strParts[13], "PartName");
                        if (strParts[15].EndsWith(" "))
                            strParts[15] = strParts[15] + GetAttribute(TitlesXml, strParts[14], "PartName");
                        else
                            strParts[15] = strParts[15] + ' ' + GetAttribute(TitlesXml, strParts[14], "PartName");
                    }
                }
                */
                for (int partindex = 0; partindex < 21; partindex++)
                {
                    // All sections
                    // read the xml values
                    bFound = false;

                    for (int ndcnt = 0; ndcnt < ndparent.Nodes.Count; ndcnt++)
                    {
                        if (ndparent.Nodes[ndcnt].Text == strParts[partindex])
                        {
                            bFound = true;
                            ndparent = ndparent.Nodes[ndcnt];
                            break;
                        }
                    }
                    if (!bFound)
                    {
                        ndchild = new TreeNode();
                        ndchild.Text = strParts[partindex];
                        ndchild.Expand();
                        ndparent.Nodes.Add(ndchild);
                        ndparent = ndchild;
                    }
                }
            }

            List<string> listNames = new List<string>();

            XmlTextWriter writer = new XmlTextWriter(DataPath + "default.xml", new System.Text.ASCIIEncoding());
            writer.Formatting = Formatting.Indented;
            writer.Indentation = 2;
            writer.WriteStartDocument();
            writer.WriteComment("Comment");
            writer.WriteStartElement("INI");

            for (int ndcntrt = 0; ndcntrt < ndroot.Nodes.Count; ndcntrt++)
            {
                TreeNode ndtype = ndroot.Nodes[ndcntrt];
                for (int ndcnttype = 0; ndcnttype < ndtype.Nodes.Count; ndcnttype++)
                {
                    TreeNode ndpart1 = ndtype.Nodes[ndcnttype];

                    for (int ndcntpart1 = 0; ndcntpart1 < ndpart1.Nodes.Count; ndcntpart1++)
                    {
                        TreeNode ndpart2 = ndpart1.Nodes[ndcntpart1];

                        for (int ndcntpart2 = 0; ndcntpart2 < ndpart2.Nodes.Count; ndcntpart2++)
                        {
                            TreeNode ndpart3 = ndpart2.Nodes[ndcntpart2];
                            for (int ndcntpart3 = 0; ndcntpart3 < ndpart3.Nodes.Count; ndcntpart3++)
                            {
                                TreeNode ndpart4 = ndpart3.Nodes[ndcntpart3];

                                for (int ndcntpart4 = 0; ndcntpart4 < ndpart4.Nodes.Count; ndcntpart4++)
                                {
                                    TreeNode ndpart5 = ndpart4.Nodes[ndcntpart4];

                                    for (int ndcntpart5 = 0; ndcntpart5 < ndpart5.Nodes.Count; ndcntpart5++)
                                    {
                                        TreeNode ndpart6 = ndpart5.Nodes[ndcntpart5];

                                        for (int ndcntpart6 = 0; ndcntpart6 < ndpart6.Nodes.Count; ndcntpart6++)
                                        {
                                            TreeNode ndpart7 = ndpart6.Nodes[ndcntpart6];

                                            for (int ndcntpart7 = 0; ndcntpart7 < ndpart7.Nodes.Count; ndcntpart7++)
                                            {
                                                TreeNode ndpart8 = ndpart7.Nodes[ndcntpart7];

                                                for (int ndcntpart8 = 0; ndcntpart8 < ndpart8.Nodes.Count; ndcntpart8++)
                                                {
                                                    TreeNode ndpart9 = ndpart8.Nodes[ndcntpart8];

                                                    for (int ndcntpart9 = 0; ndcntpart9 < ndpart9.Nodes.Count; ndcntpart9++)
                                                    {
                                                        TreeNode ndpart10 = ndpart9.Nodes[ndcntpart9];

                                                        for (int ndcntpart10 = 0; ndcntpart10 < ndpart10.Nodes.Count; ndcntpart10++)
                                                        {
                                                            TreeNode ndpart11 = ndpart10.Nodes[ndcntpart10];

                                                            for (int ndcntpart11 = 0; ndcntpart11 < ndpart11.Nodes.Count; ndcntpart11++)
                                                            {
                                                                TreeNode ndpart12 = ndpart11.Nodes[ndcntpart11];

                                                                for (int ndcntpart12 = 0; ndcntpart12 < ndpart12.Nodes.Count; ndcntpart12++)
                                                                {
                                                                    TreeNode ndpart13 = ndpart12.Nodes[ndcntpart12];

                                                                    for (int ndcntpart13 = 0; ndcntpart13 < ndpart13.Nodes.Count; ndcntpart13++)
                                                                    {
                                                                        TreeNode ndpart14 = ndpart13.Nodes[ndcntpart13];

                                                                        for (int ndcntpart14 = 0; ndcntpart14 < ndpart14.Nodes.Count; ndcntpart14++)
                                                                        {

                                                                            TreeNode ndpart15 = ndpart14.Nodes[ndcntpart14];
                                                                            for (int ndcntpart15 = 0; ndcntpart15 < ndpart15.Nodes.Count; ndcntpart15++)
                                                                            {
                                                                                TreeNode ndpart16 = ndpart15.Nodes[ndcntpart15];
                                                                                for (int ndcntpart16 = 0; ndcntpart16 < ndpart16.Nodes.Count; ndcntpart16++)
                                                                                {
                                                                                    TreeNode ndpart17 = ndpart16.Nodes[ndcntpart16];
                                                                                    for (int ndcntpart17 = 0; ndcntpart17 < ndpart17.Nodes.Count; ndcntpart17++)
                                                                                    {
                                                                                        TreeNode ndpart18 = ndpart17.Nodes[ndcntpart17];
                                                                                        for (int ndcntpart18 = 0; ndcntpart18 < ndpart18.Nodes.Count; ndcntpart18++)
                                                                                        {
                                                                                            TreeNode ndpart19 = ndpart18.Nodes[ndcntpart18];
                                                                                            for (int ndcntpart19 = 0; ndcntpart19 < ndpart19.Nodes.Count; ndcntpart19++)
                                                                                            {
                                                                                                TreeNode ndpart20 = ndpart19.Nodes[ndcntpart19];

                                                                                                string NewName = "";

                                                                                                if (listNames.Contains(ndpart15.Text))
                                                                                                {
                                                                                                    int nCount = 1;
                                                                                                    while (listNames.Contains(ndpart15.Text + " (Copy " + nCount + ")"))
                                                                                                        nCount++;

                                                                                                    NewName = ndpart15.Text + " (Copy " + nCount + ")";
                                                                                                }
                                                                                                else
                                                                                                {
                                                                                                    NewName = ndpart15.Text;
                                                                                                }

                                                                                                listNames.Add(NewName);

                                                                                                writer.WriteStartElement("Section");
                                                                                                //writer.WriteAttributeString("Name", NewName);
                                                                                                writer.WriteElementString("Name", NewName);
                                                                                                writer.WriteElementString("Type", ndtype.Text);
                                                                                                writer.WriteElementString("Rating", ndpart16.Text);
                                                                                                writer.WriteElementString("Description", ndpart17.Text.Replace('\"', ' ').Trim());

                                                                                                writer.WriteElementString("Part1", ndpart1.Text);
                                                                                                writer.WriteElementString("Part2", ndpart2.Text);
                                                                                                writer.WriteElementString("Part3", ndpart3.Text);
                                                                                                writer.WriteElementString("Part4", ndpart4.Text);
                                                                                                writer.WriteElementString("Part5", ndpart5.Text);
                                                                                                writer.WriteElementString("Part6", ndpart6.Text);
                                                                                                writer.WriteElementString("Part7", ndpart7.Text);
                                                                                                writer.WriteElementString("Part8", ndpart8.Text);
                                                                                                writer.WriteElementString("Part9", ndpart9.Text);
                                                                                                writer.WriteElementString("Part10", ndpart10.Text);
                                                                                                writer.WriteElementString("Part11", ndpart11.Text);
                                                                                                writer.WriteElementString("Part12", ndpart12.Text);
                                                                                                writer.WriteElementString("Part13", ndpart13.Text);
                                                                                                writer.WriteElementString("Part14", ndpart14.Text);
                                                                                                writer.WriteElementString("RemAmmo_Quantity", ndpart18.Text);
                                                                                                writer.WriteElementString("Quality", ndpart19.Text);
                                                                                                writer.WriteElementString("Level", ndpart20.Text);
                                                                                                writer.WriteEndElement();
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            writer.WriteEndElement();
            writer.WriteEndDocument();
            writer.Flush();
            writer.Close();


        }
        
        public void DoPartsCategory(string Category, TreeView Tree)
        {
            XmlFile PartList = new XmlFile(DataPath + Category + ".txt");

            TreeNode TempNode = new TreeNode();
            TempNode.Name = Category;
            TempNode.Text = Category;
            //TempNode.Style.ApplyStyle(elementStyle16);
            foreach (string section in PartList.stListSectionNames())
            {
                TreeNode Part = new TreeNode();
                Part.Name = section;
                Part.Text = section;
                TempNode.Nodes.Add(Part);

            }
            Tree.Nodes.Add(TempNode);

        }
        public void DoTabs()
        {
            string TabsLine = System.IO.File.ReadAllText(DataPath + "weapon_tabs.txt");
            string[] TabsList = TabsLine.Split(new char[] { (char)';' });
            for (int Progress = 0; Progress < TabsList.Length; Progress++) DoPartsCategory(TabsList[Progress], PartCategoriesWeapon);
            string TabsLine2 = System.IO.File.ReadAllText(DataPath + "item_tabs.txt");
            string[] TabsList2 = TabsLine2.Split(new char[] { (char)';' });
            for (int Progress = 0; Progress < TabsList2.Length; Progress++) DoPartsCategory(TabsList2[Progress], PartCategoriesItem);

        }

        // Functions to populate ComboBoxes
        public void DoQuestList()
        {
            XmlFile QuestsXml = new XmlFile(DataPath + "Quests.ini");

            foreach (string section in QuestsXml.stListSectionNames())
                QuestList.Items.Add(QuestsXml.XmlReadValue(section, "MissionName"));

        }
        public void DoEchoList()
        {
            XmlFile EchoesXml = new XmlFile(DataPath + "Echos.ini");

            foreach (string section in EchoesXml.stListSectionNames())
            {
                string name = EchoesXml.XmlReadValue(section, "Subject");
                if (name != "")
                    EchoList.Items.Add(name);
                else
                    EchoList.Items.Add(section);
            }

            //for (int Progress = 0; Progress < PartList.stListSectionNames().Count; Progress++)
            //{
            //    string name = PartList.XmlReadValue(PartList.stListSectionNames()[Progress], "Subject");
            //    if (name != "")
            //        EchoList.Items.Add(name);
            //    else EchoList.Items.Add(PartList.stListSectionNames()[Progress]);
            //}

        }
        public void DoLocationsList()
        {
            LocationsList.Items.Clear();
            CurrentLocation.Items.Clear();

            XmlFile LocationsXml = new XmlFile(DataPath + "Locations.ini");
            foreach (string section in LocationsXml.stListSectionNames())
            {
                string outpostname = LocationsXml.XmlReadValue(section, "OutpostDisplayName");
                LocationsList.Items.Add(outpostname);
                CurrentLocation.Items.Add(outpostname);
            }
        }
        public void DoSkillList()
        {
            SkillList.Items.Clear();
            string SkillFileName;
            switch ((string)Class.SelectedItem)
            {
                case "Soldier":
                    SkillFileName = "gd_skills2_Roland.txt";
                    break;
                case "Siren":
                    SkillFileName = "gd_Skills2_Lilith.txt";
                    break;
                case "Hunter":
                    SkillFileName = "gd_skills2_Mordecai.txt";
                    break;
                case "Berserker":
                    SkillFileName = "gd_Skills2_Brick.txt";
                    break;
                default:
                    SkillFileName = "gd_skills_common.txt";
                    break;
            }
            XmlFile SkillsXml = new XmlFile(DataPath + SkillFileName);
            foreach (string section in SkillsXml.stListSectionNames())
                SkillList.Items.Add((string)SkillsXml.XmlReadValue(section, "SkillName"));
        }

        private void ResolveWeaponNames()
        {
            WeaponNames.Clear();
            foreach (List<string> Parts in CurrentWSG.WeaponStrings)
            {
                WeaponNames.Add(GetWeaponNameAdvanced(Parts));
            }
        }
        private void ResolveItemNames()
        {
            ItemNames.Clear();
            foreach (List<string> Parts in CurrentWSG.ItemStrings)
            {
                ItemNames.Add(GetItemNameAdvanced(Parts));
            }
        }

        private void TrySelectedNode(TreeView DesiredTree, int SelectedIndex)
        {
            try
            {
                DesiredTree.SelectedNode = DesiredTree.Nodes[SelectedIndex];
            }
            catch
            {
                if (SelectedIndex > 0)
                    DesiredTree.SelectedNode = DesiredTree.Nodes[SelectedIndex - 1];
                else
                    DesiredTree.SelectedNode = null;
            }
            if (DesiredTree.SelectedNode != null)
                DesiredTree.SelectedNode.EnsureVisible();
        }
        private void TrySelectedNode(TreeView DesiredTree, int RootNodeIndex, int SelectedIndex)
        {
            try { DesiredTree.SelectedNode = DesiredTree.Nodes[RootNodeIndex].Nodes[SelectedIndex]; }
            catch { DesiredTree.SelectedNode = DesiredTree.Nodes[RootNodeIndex].Nodes[SelectedIndex - 1]; }
            DesiredTree.SelectedNode.EnsureVisible();
        }

        #endregion    
        #region <<<<< ARRAY FUNCTIONS >>>>>

        //Resizes arrays. I really should just convert everything to lists...
        private void ResizeArrayLarger(ref string[,] Input, int rows, int cols)
        {
            string[,] newArray = new string[rows, cols];
            Array.Copy(Input, newArray, Input.Length);
            Input = newArray;
        }
        private void ResizeArraySmaller(ref string[,] Input, int rows, int cols)
        {
            string[,] newArray = new string[rows, cols];
            Array.Copy(Input, 0, newArray, 0, (long)(rows * cols));
            Input = newArray;
        }
        private void ResizeArrayLarger(ref string[] Input, int rows)
        {
            string[] newArray = new string[rows];
            Array.Copy(Input, newArray, Input.Length);
            Input = newArray;
        }
        private void ResizeArraySmaller(ref string[] Input, int rows)
        {
            string[] newArray = new string[rows];
            Array.Copy(Input, 0, newArray, 0, (long)rows);
            Input = newArray;
        }
        private void ResizeArrayLarger(ref int[,] Input, int rows, int cols)
        {
            int[,] newArray = new int[rows, cols];
            Array.Copy(Input, newArray, Input.Length);
            Input = newArray;
        }
        private void ResizeArraySmaller(ref int[,] Input, int rows, int cols)
        {
            int[,] newArray = new int[rows, cols];
            Array.Copy(Input, 0, newArray, 0, (long)((rows) * cols));
            Input = newArray;
        }
        private void ResizeArrayLarger(ref int[] Input, int rows)
        {
            int[] newArray = new int[rows];
            Array.Copy(Input, newArray, Input.Length);
            Input = newArray;
        }
        private void ResizeArraySmaller(ref int[] Input, int rows)
        {
            int[] newArray = new int[rows];
            Array.Copy(Input, 0, newArray, 0, (long)rows);
            Input = newArray;
        }
        private void ResizeArrayLarger(ref float[] Input, int rows)
        {
            float[] newArray = new float[rows];
            Array.Copy(Input, newArray, Input.Length);
            Input = newArray;
        }
        private void ResizeArraySmaller(ref float[] Input, int rows)
        {
            float[] newArray = new float[rows];
            Array.Copy(Input, 0, newArray, 0, (long)rows);
            Input = newArray;
        }

        #endregion
        #region <<<<< SHARED FUNCTIONS >>>>>

        private void DoWindowTitle()
        {
            this.Text = "WillowTree# - " + CharacterName.Text + "  Level " + Level.Value + " " + Class.Text + " (" + CurrentWSG.Platform + ")";
        }

        private string LevelTranslator(object obj)
        {
            SlideSelector levelindex = (SlideSelector)obj;

            if (levelindex.InputMode == InputMode.Advanced)
            {
                if (GlobalSettings.UseHexInAdvancedMode == true)
                    return "Level Index (hexadecimal)";
                else
                    return "Level Index (decimal)";
            }

            if (levelindex.Value == 0)
                return "Level: Default";
            else
                return "Level: " + (levelindex.Value - 2);
        }
        private string QualityTranslator(object obj)
        {
            SlideSelector qualityindex = (SlideSelector)obj;

            if (qualityindex.InputMode == InputMode.Advanced)
            {
                if (GlobalSettings.UseHexInAdvancedMode == true)
                    return "Quality Index (hexadecimal)";
                else
                    return "Quality Index (decimal)";
            }
            else
                return "Quality: " + qualityindex.Value;
        }

        private void ThrowExceptionIfIntString(string StringVal)
        {
            int tempValue;
            if (int.TryParse(StringVal, out tempValue))
                throw new System.FormatException();
        }

        private int Int32FromString(string Int32AsString, int ValueIfEmpty)
        {
            if (Int32AsString == "")
                return ValueIfEmpty;
            return Convert.ToInt32(Int32AsString);
        }

        public bool CheckIfNull(string[] Array)
        {
            try
            {
                if (Array.Length > 0)
                    return false;
                else
                    return true;
            }
            catch { return true; }
        }

        #endregion

        #region <<<<< MAIN WINDOW >>>>>

        public WillowTreeMain()
        {
            InitializeComponent();

            UpdateButton.Hide();

            LockerTab.Select();
            if (System.IO.Directory.Exists(DataPath) == false)
            {
                MessageBox.Show("Couldn't find the 'Data' folder! Please make sure that WillowTree# and the 'Data' folder are in the same directory.");
                Application.Exit();
            }
            //DoTabs();

            //DoLockerTree(DataPath + "default.wtl");
            GeneralTab.Enabled = false;
            SkillsTab.Enabled = false;
            AmmoTab.Enabled = false;
            ItemsTab.Enabled = false;
            WeaponsTab.Enabled = false;
            QuestsTab.Enabled = false;
            EchoesTab.Enabled = false;
            LockerTab.Enabled = true;
            ExportToBackpack.Enabled = false;
            ImportAllFromItems.Enabled = false;
            ImportAllFromWeapons.Enabled = false;

            if (System.Diagnostics.Debugger.IsAttached == true) DebugTab.Enabled = true;
            else
            {
                DebugTab.Enabled = false;
                DebugTab.Visible = false;
            }
            Save.Enabled = false;
            SaveAs.Enabled = false;
            SelectFormat.Enabled = false;

            //DoLocationsList();
            //DoQuestList();
            //DoEchoList();
        }

        private void WillowTreeMain_Load(object sender, EventArgs e)
        {
            StartUpFunctions();

#if !DEBUG
            // Only check for new version if it's not a debug build.
            ThreadPool.QueueUserWorkItem(CheckVersion);
#endif
        }

        public void StartUpFunctions()
        {
            DoTabs();
            if (System.IO.File.Exists(DataPath + "default.xml") == false)
                System.IO.File.WriteAllText(DataPath + "default.xml", "<?xml version=\"1.0\" encoding=\"us-ascii\"?>\r\n<INI></INI>\r\n");

            try
            {
                DoLockerTreeNodupe(DataPath + "default.xml");
                DoLockerTree(DataPath + "default.xml");
            }
            catch
            {
                MessageBox.Show("The locker file \"" + DataPath + "default.xml\" could not be loaded.  It may be corrupt.  If you delete it the program will make a new one and you may be able to start the program successfully.  Shutting down now.");
                Application.Exit();
                return;
            }


            DoLocationsList();
            DoQuestList();
            DoEchoList();
            setXPchart();
        }

        private void Open_Click(object sender, EventArgs e)
        {
            textBox1.Clear();

            OpenFileDialog tempOpen = new OpenFileDialog();
            tempOpen.DefaultExt = "*.sav";
            tempOpen.Filter = "WillowSaveGame(*.sav)|*.sav";

            if (tempOpen.ShowDialog() == DialogResult.OK)
                try
                {
                    BankSpace.Enabled = false;
                    BankSpace.Value = 0;
                    CurrentWSG = new WillowSaveGame();
                    CurrentWSG.LoadWSG(tempOpen.FileName);

                    XmlFile LocationsXml = new XmlFile(DataPath + "Locations.ini");
                    setXPchart();
                    textBox1.AppendText(CurrentWSG.Platform);
                    CharacterName.Text = CurrentWSG.CharacterName;
                    try
                    {
                        if (CurrentWSG.Level <= Level.Maximum)
                            Level.Value = CurrentWSG.Level;
                        else
                            Level.Value = Level.Maximum;

                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        MessageBox.Show("The level value was outside the acceptable range. Adjust your level and experience to their correct values.\r\nLevel: " + CurrentWSG.Level + "\r\nExperience: " + CurrentWSG.Experience);
                        Level.Value = 1;
                        Experience.Value = 0;
                    }
                    try
                    {
                        if (CurrentWSG.Experience >= Experience.Minimum)
                            Experience.Value = CurrentWSG.Experience;
                        else
                            Experience.Value = Experience.Minimum;

                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        MessageBox.Show("The experience value was outside the acceptable range. Adjust your level and experience to their correct values.\r\nLevel: " + CurrentWSG.Level + "\r\nExperience: " + CurrentWSG.Experience);

                        Experience.Value = Experience.Minimum;
                    }
                    if (CurrentWSG.SkillPoints <= SkillPoints.Maximum)
                        SkillPoints.Value = CurrentWSG.SkillPoints;
                    else
                        SkillPoints.Value = SkillPoints.Maximum;
                    PT2Unlocked.SelectedIndex = CurrentWSG.FinishedPlaythrough1;
                    try
                    {
                        Cash.Value = CurrentWSG.Cash;
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        Cash.Value = Cash.Maximum;
                        MessageBox.Show("This save has $" + CurrentWSG.Cash + ", which is outside of WillowTree#'s limits and can cause in-game issues. Because of this, your cash has been lowered. It is suggested that you further reduce your cash to prevent future problems.");
                    }
                    BackpackSpace.Value = CurrentWSG.BackpackSize;
                    EquipSlots.Value = CurrentWSG.EquipSlots;
                    SaveNumber.Value = CurrentWSG.SaveNumber;
                    CurrentLocation.SelectedItem = LocationsXml.XmlReadValue(CurrentWSG.CurrentLocation, "OutpostDisplayName");
                    if (CurrentWSG.Class == "gd_Roland.Character.CharacterClass_Roland") Class.SelectedIndex = 0;
                    else if (CurrentWSG.Class == "gd_lilith.Character.CharacterClass_Lilith") Class.SelectedIndex = 1;
                    else if (CurrentWSG.Class == "gd_mordecai.Character.CharacterClass_Mordecai") Class.SelectedIndex = 2;
                    else if (CurrentWSG.Class == "gd_Brick.Character.CharacterClass_Brick") Class.SelectedIndex = 3;
                    textBox1.AppendText("\r\nHeader: " + CurrentWSG.MagicHeader + "\r\nVersion: " + CurrentWSG.VersionNumber + "\r\nPlyr String: " + CurrentWSG.PLYR + "\r\nRevision Number: " + CurrentWSG.RevisionNumber + "\r\nClass: " + CurrentWSG.Class + "\r\nLevel: " + CurrentWSG.Level + "\r\nExp: " + CurrentWSG.Experience + "\r\nSkill Points: " + CurrentWSG.SkillPoints + "\r\nunknown1: " + CurrentWSG.Unknown1 + "\r\nMoney: " + CurrentWSG.Cash + "\r\nFinished Game: " + CurrentWSG.FinishedPlaythrough1 + "\r\nNumber of skills: " + CurrentWSG.NumberOfSkills + "\r\nCurrent Quest: " + CurrentWSG.CurrentQuest + "\r\nTotal PT1 Quests: " + CurrentWSG.TotalPT1Quests + "\r\nSecondary Quest: " + CurrentWSG.SecondaryQuest + "\r\nTotal PT2 Quests: " + CurrentWSG.TotalPT2Quests + "\r\nUnknown PT1 Quest Value: " + CurrentWSG.UnknownPT1QuestValue);
                    ActivePT1Quest.Text = CurrentWSG.CurrentQuest;
                    ActivePT2Quest.Text = CurrentWSG.SecondaryQuest;

                    ResolveWeaponNames();
                    ResolveItemNames();

                    DoQuestTree();
                    DoLocationTree();
                    DoSkillTree();
                    DoEchoTree();
                    DoAmmoTree();
                    DoWeaponTree();
                    DoItemTree();
                    DoSkillList();

                    GeneralTab.Enabled = true;
                    AmmoTab.Enabled = true;
                    SkillsTab.Enabled = true;
                    EchoesTab.Enabled = true;
                    LockerTab.Enabled = true;
                    ExportToBackpack.Enabled = true;
                    ImportAllFromItems.Enabled = true;
                    ImportAllFromWeapons.Enabled = true;
                    WeaponsTab.Enabled = true;
                    ItemsTab.Enabled = true;
                    QuestsTab.Enabled = true;
                    Save.Enabled = true;
                    SaveAs.Enabled = true;
                    SelectFormat.Enabled = true;

                    if (CurrentWSG.DLC.BankSize > 0)
                    {
                        BankSpace.Value = CurrentWSG.DLC.BankSize;
                        BankSpace.Enabled = true;
                    }
                    DoWindowTitle();
                }

                catch
                {

                    if (CurrentWSG.EchoStringsPT2 == null && CurrentWSG.NumberOfEchosPT2 > 0 && CurrentWSG.TotalPT2Quests > 1 && CurrentWSG.NumberOfEchosPT2 < 300)
                        MessageBox.Show("Error reading PT2 echo logs.");
                    else
                        MessageBox.Show("Could not open save.");
                    BankSpace.Enabled = false;
                    BankSpace.Value = 0;
                    GeneralTab.Enabled = false;
                    AmmoTab.Enabled = false;
                    SkillsTab.Enabled = false;
                    EchoesTab.Enabled = false;
                    //WTLTab.Enabled = false;
                    ExportToBackpack.Enabled = false;
                    ImportAllFromItems.Enabled = false;
                    ImportAllFromWeapons.Enabled = false;
                    WeaponsTab.Enabled = false;
                    ItemsTab.Enabled = false;
                    QuestsTab.Enabled = false;
                    Save.Enabled = false;
                    SaveAs.Enabled = false;
                    LockerTab.Select();
                    textBox1.AppendText("\r\nHeader: " + CurrentWSG.MagicHeader + "\r\nVersion: " + CurrentWSG.VersionNumber + "\r\nPlyr String: " + CurrentWSG.PLYR + "\r\nRevision Number: " + CurrentWSG.RevisionNumber + "\r\nClass: " + CurrentWSG.Class + "\r\nLevel: " + CurrentWSG.Level + "\r\nExp: " + CurrentWSG.Experience + "\r\nSkill Points: " + CurrentWSG.SkillPoints + "\r\nunknown1: " + CurrentWSG.Unknown1 + "\r\nMoney: " + CurrentWSG.Cash + "\r\nFinished Game: " + CurrentWSG.FinishedPlaythrough1 + "\r\nNumber of skills: " + CurrentWSG.NumberOfSkills + "\r\nCurrent Quest: " + CurrentWSG.CurrentQuest + "\r\nTotal PT1 Quests: " + CurrentWSG.TotalPT1Quests + "\r\nSecondary Quest: " + CurrentWSG.SecondaryQuest + "\r\nTotal PT2 Quests: " + CurrentWSG.TotalPT2Quests + "\r\nUnknown PT1 Quest Value: " + CurrentWSG.UnknownPT1QuestValue);
                }
        }
        private void Save_Click(object sender, EventArgs e)
        {
            try
            {
                File.Copy(CurrentWSG.OpenedWSG, CurrentWSG.OpenedWSG + ".bak0", true);
                if (File.Exists(CurrentWSG.OpenedWSG + ".bak10") == true)
                    File.Delete(CurrentWSG.OpenedWSG + ".bak10");
                for (int i = 9; i >= 0; i--)
                {
                    if (File.Exists(CurrentWSG.OpenedWSG + ".bak" + i) == true)
                        File.Move(CurrentWSG.OpenedWSG + ".bak" + i, CurrentWSG.OpenedWSG + ".bak" + (i + 1));
                }
            }
            catch { }

            try
            {
                SaveToFile(CurrentWSG.OpenedWSG);
                MessageBox.Show("Saved WSG to: " + CurrentWSG.OpenedWSG);
            }
            catch { MessageBox.Show("Couldn't save WSG"); }
        }
        private void SaveAs_Click(object sender, EventArgs e)
        {
            SaveFileDialog tempSave = new SaveFileDialog();
            tempSave.DefaultExt = "*.sav";
            tempSave.Filter = "WillowSaveGame(*.sav)|*.sav";

            tempSave.FileName = CurrentWSG.OpenedWSG;

            if (tempSave.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    SaveToFile(tempSave.FileName);
                    MessageBox.Show("Saved WSG to: " + CurrentWSG.OpenedWSG);
                    Save.Enabled = true;
                }
                catch { MessageBox.Show("Couldn't save WSG"); }
            }
        }
        private void PCFormat_Click(object sender, EventArgs e)
        {
            if (CurrentWSG.Platform == "PC")
                return;
            if ((CurrentWSG.ContainsRawData == true) && (CurrentWSG.EndianWSG != ByteOrder.LittleEndian))
            {
                MessageBox.Show("This savegame contains raw data that could not be parsed so it cannot be exported to a different machine byte order.");
                return;
            }

            CurrentWSG.Platform = "PC";
            CurrentWSG.EndianWSG = ByteOrder.LittleEndian;
            DoWindowTitle();
            Save.Enabled = false;
        }
        private void PS3Format_Click(object sender, EventArgs e)
        {
            if (CurrentWSG.Platform == "PS3")
                return;
            if ((CurrentWSG.ContainsRawData == true) && (CurrentWSG.EndianWSG != ByteOrder.BigEndian))
            {
                MessageBox.Show("This savegame contains raw data that could not be parsed so it cannot be exported to a different machine byte order.");
                return;
            }
            CurrentWSG.Platform = "PS3";
            CurrentWSG.EndianWSG = ByteOrder.BigEndian;
            DoWindowTitle();
            MessageBox.Show("This save data will be stored in the PS3 format. Please note that you will require \r\nproper SFO, PNG, and PFD files to be transfered back to the \r\nPS3. These can be acquired from another Borderlands save \r\nfor the same profile.");
            Save.Enabled = false;
        }
        private void XBoxFormat_Click(object sender, EventArgs e)
        {
            if (CurrentWSG.Platform == "X360")
                return;
            if ((CurrentWSG.ContainsRawData == true) && (CurrentWSG.EndianWSG != ByteOrder.BigEndian))
            {
                MessageBox.Show("This savegame contains raw data that could not be parsed so it cannot be exported to a different machine byte order.");
                return;
            }

            if (CurrentWSG.DeviceID == null)
            {
                XBoxIDDialog dlgXBoxID = new XBoxIDDialog();
                if (dlgXBoxID.ShowDialog() == DialogResult.OK)
                {
                    CurrentWSG.ProfileID = dlgXBoxID.ID.ProfileID;
                    int DeviceIDLength = dlgXBoxID.ID.DeviceID.Count();
                    CurrentWSG.DeviceID = new byte[DeviceIDLength];
                    Array.Copy(dlgXBoxID.ID.DeviceID, CurrentWSG.DeviceID, DeviceIDLength);
                }
                else
                    return;
            }
            CurrentWSG.Platform = "X360";
            CurrentWSG.EndianWSG = ByteOrder.BigEndian;
            DoWindowTitle();
            CurrentWSG.OpenedWSG = "";
            Save.Enabled = false;
        }
        private void ExitWT_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void StandardInput_Click(object sender, EventArgs e)
        {
            GlobalSettings.InputMode = InputMode.Standard;
        }
        private void AdvancedInputDecimal_Click(object sender, EventArgs e)
        {
            GlobalSettings.UseHexInAdvancedMode = false;
            GlobalSettings.InputMode = InputMode.Advanced;
        }
        private void AdvancedInputHexadecimal_Click(object sender, EventArgs e)
        {
            GlobalSettings.UseHexInAdvancedMode = true;
            GlobalSettings.InputMode = InputMode.Advanced;
        }

        private void SaveToFile(string filename)
        {
            XmlFile LocationsXml = new XmlFile(DataPath + "Locations.ini");

            if (BankSpace.Enabled)
                CurrentWSG.DLC.BankSize = (int)BankSpace.Value;

            if (Class.SelectedIndex == 0) CurrentWSG.Class = "gd_Roland.Character.CharacterClass_Roland";
            else if (Class.SelectedIndex == 1) CurrentWSG.Class = "gd_lilith.Character.CharacterClass_Lilith";
            else if (Class.SelectedIndex == 2) CurrentWSG.Class = "gd_mordecai.Character.CharacterClass_Mordecai";
            else if (Class.SelectedIndex == 3) CurrentWSG.Class = "gd_Brick.Character.CharacterClass_Brick";
            CurrentWSG.CharacterName = CharacterName.Text;
            CurrentWSG.Level = (int)Level.Value;
            CurrentWSG.Experience = (int)Experience.Value;
            CurrentWSG.SkillPoints = (int)SkillPoints.Value;
            CurrentWSG.FinishedPlaythrough1 = PT2Unlocked.SelectedIndex;
            CurrentWSG.Cash = (int)Cash.Value;
            CurrentWSG.BackpackSize = (int)BackpackSpace.Value;
            CurrentWSG.EquipSlots = (int)EquipSlots.Value;
            CurrentWSG.SaveNumber = (int)SaveNumber.Value;
            if (CurrentLocation.SelectedText != "" && CurrentLocation.SelectedText != null)
                CurrentWSG.CurrentLocation = LocationsXml.stListSectionNames()[CurrentLocation.SelectedIndex];

            CurrentWSG.SaveWSG(filename);
            CurrentWSG.OpenedWSG = filename;
        }
     
        #endregion
        #region <<<<< MAIN PANEL >>>>>

        private void CheckVerPopup(object sender, PaintEventArgs e)
        {
            if (VersionFromServer != Version.Text && VersionFromServer != "" && VersionFromServer != null)
            {
                UpdateButton.Text = "Version " + VersionFromServer + " is now available! Click here to download.";
                UpdateButton.Show();
                //t1.Join();
            }
        }
        private void CheckVerPopup(object sender, MouseEventArgs e)
        {
            if (VersionFromServer != Version.Text && VersionFromServer != "" && VersionFromServer != null)
            {
                UpdateButton.Text = "Version " + VersionFromServer + " is now available! Click here to download.";
                UpdateButton.Show();
                //t1.Join();
            }
        }

        //Recovers the latest version from the sourceforge server.
        public void CheckVersion(object state)
        {
            try
            {
                using (WebClient webClient = new WebClient())
                {
                    string VersionTextFromServer = webClient.DownloadString("http://willowtree.sourceforge.net/version.txt");
                    string[] RemoteVersionInfo = VersionTextFromServer.Replace("\r\n", "\n").Split('\n');
                    if ((RemoteVersionInfo.Count() > 1) || (RemoteVersionInfo.Count() <= 3))
                    {
                        VersionFromServer = RemoteVersionInfo[0];
                        DownloadURLFromServer = RemoteVersionInfo[1];
                    }
                }
            }
            catch { }
        }

        private void UpdateButton_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://" + DownloadURLFromServer);
        }

        #endregion
        #region <<<<< GENERAL/LOCATIONS PANEL >>>>>

        public int[] XPChart = new int[71];

        public void setXPchart()
        {
            XPChart[0] = 0;
            XPChart[1] = 0;
            XPChart[2] = 358;
            XPChart[3] = 1241;
            XPChart[4] = 2850;
            XPChart[5] = 5376;
            XPChart[6] = 8997;
            XPChart[7] = 13886;
            XPChart[8] = 20208;
            XPChart[9] = 28126;
            XPChart[10] = 37798;
            XPChart[11] = 49377;
            XPChart[12] = 63016;
            XPChart[13] = 78861;
            XPChart[14] = 97061;
            XPChart[15] = 117757;
            XPChart[16] = 141092;
            XPChart[17] = 167207;
            XPChart[18] = 196238;
            XPChart[19] = 228322;
            XPChart[20] = 263595;
            XPChart[21] = 302190;
            XPChart[22] = 344238;
            XPChart[23] = 389873;
            XPChart[24] = 439222;
            XPChart[25] = 492414;
            XPChart[26] = 549578;
            XPChart[27] = 610840;
            XPChart[28] = 676325;
            XPChart[29] = 746158;
            XPChart[30] = 820463;
            XPChart[31] = 899363;
            XPChart[32] = 982980;
            XPChart[33] = 1071436;
            XPChart[34] = 1164850;
            XPChart[35] = 1263343;
            XPChart[36] = 1367034;
            XPChart[37] = 1476041;
            XPChart[38] = 1590483;
            XPChart[39] = 1710476;
            XPChart[40] = 1836137;
            XPChart[41] = 1967582;
            XPChart[42] = 2104926;
            XPChart[43] = 2248285;
            XPChart[44] = 2397772;
            XPChart[45] = 2553561;
            XPChart[46] = 2715586;
            XPChart[47] = 2884139;
            XPChart[48] = 3059273;
            XPChart[49] = 3241098;
            XPChart[50] = 3429728;
            // lvl 50 says 3625271
            XPChart[51] = 3628272;
            XPChart[52] = 3827841;
            XPChart[53] = 4037544;
            XPChart[54] = 4254492;
            XPChart[55] = 4478793;
            XPChart[56] = 4710557;
            XPChart[57] = 4949891;
            XPChart[58] = 5196904;
            XPChart[59] = 5451702;
            XPChart[60] = 5714395;
            XPChart[61] = 5985086;
            //Knoxx-only
            XPChart[62] = 6263885;
            XPChart[63] = 6550897;
            XPChart[64] = 6846227;
            XPChart[65] = 7149982;
            XPChart[66] = 7462266;
            XPChart[67] = 7783184;
            XPChart[68] = 8112840;
            XPChart[69] = 8451340;

            XPChart[70] = 2147483647;
        }

        private void CharacterName_TextChanged(object sender, EventArgs e)
        {
            DoWindowTitle();
        }

        private void Class_SelectedIndexChanged(object sender, EventArgs e)
        {
            DoWindowTitle();
        }

        private void DeleteLocation_Click(object sender, EventArgs e)
        {
            try
            {
                int Selected = LocationTree.SelectedNode.Index;
                CurrentWSG.TotalLocations = CurrentWSG.TotalLocations - 1;
                for (int Position = Selected; Position < CurrentWSG.TotalLocations; Position++)
                {
                    CurrentWSG.LocationStrings[Position] = CurrentWSG.LocationStrings[Position + 1];
                }
                ResizeArraySmaller(ref CurrentWSG.LocationStrings, CurrentWSG.TotalLocations);
                DoLocationTree();

                LocationTree.SelectedNode = LocationTree.Nodes[Selected];
            }
            catch { }
        }

        private void Level_ValueChanged(object sender, EventArgs e)
        {
            if (Level.Value > 0 && Level.Value < 70)
            {
                Experience.Minimum = XPChart[(int)Level.Value];

            }
            else
            {
                Experience.Minimum = 0;
            }
            DoWindowTitle();
        }

        private void LocationsList_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                XmlFile LocationsXml = new XmlFile(DataPath + "Locations.ini");
                int SelectedItem = LocationsList.SelectedIndex;
                CurrentWSG.TotalLocations = CurrentWSG.TotalLocations + 1;
                ResizeArrayLarger(ref CurrentWSG.LocationStrings, CurrentWSG.TotalLocations);
                CurrentWSG.LocationStrings[CurrentWSG.TotalLocations - 1] = LocationsXml.stListSectionNames()[SelectedItem];
                DoLocationTree();
            }
            catch { }
        }

        #endregion
        #region <<<<< WEAPON PANEL >>>>>

        #region ---- Weapon List Functions ----
        private void AddWeapon(string Name, List<string> Parts, List<int> Values)
        {   // This doesn't create a new copy of the elements.
            CurrentWSG.WeaponStrings.Add(Parts);
            CurrentWSG.WeaponValues.Add(Values);
            WeaponNames.Add(Name);
            CurrentWSG.NumberOfWeapons++;
        }
        private void CopyWeapon(int SourceIndex, int DestinationIndex)
        {   // Use new here to create a new copy of the elements.
            CurrentWSG.WeaponStrings[DestinationIndex] = new List<string>(CurrentWSG.WeaponStrings[SourceIndex]);
            CurrentWSG.WeaponValues[DestinationIndex] = new List<int>(CurrentWSG.WeaponValues[SourceIndex]);
            WeaponNames[DestinationIndex] = WeaponNames[DestinationIndex];
        }
        private void DuplicateWeapon(int Index)
        {   // Use new here to create a new copy of the elements.
            CurrentWSG.WeaponStrings.Add(new List<string>(CurrentWSG.WeaponStrings[Index]));
            CurrentWSG.WeaponValues.Add(new List<int>(CurrentWSG.WeaponValues[Index]));
            WeaponNames.Add(WeaponNames[Index]);
            CurrentWSG.NumberOfWeapons++;
        }
        private void InsertWeapon(int Index, string Name, List<string> Parts, List<int> Values)
        {
            CurrentWSG.WeaponStrings.Insert(Index, Parts);
            CurrentWSG.WeaponValues.Insert(Index, Values);
            WeaponNames.Insert(Index, Name);
            CurrentWSG.NumberOfWeapons++;
        }
        private void RemoveWeapon(int Index)
        {
            CurrentWSG.WeaponStrings.RemoveAt(Index);
            CurrentWSG.WeaponValues.RemoveAt(Index);
            WeaponNames.RemoveAt(Index);
            CurrentWSG.NumberOfWeapons--;
        }
        #endregion

        public int GetExtraStats(string[] WeaponParts, string StatName)
        {
            try
            {
                double ExtraDamage = 0;
                for (int i = 3; i < 14; i++)
                    if (WeaponParts[i].Contains("."))
                        ExtraDamage = ExtraDamage + Conversion.Val(new XmlFile(DataPath + WeaponParts[i].Substring(0, WeaponParts[i].IndexOf(".")) + ".txt").XmlReadValue(WeaponParts[i].Substring(WeaponParts[i].IndexOf(".") + 1), StatName));

                if (StatName == "TechLevelIncrease")
                    return (int)ExtraDamage;
                else
                    return (int)((ExtraDamage) * 100);
            }
            catch
            {
                return -1;
            }
        }

        private void DeletePartWeapon_Click(object sender, EventArgs e)
        {
            if (PartsWeapon.SelectedIndex != -1)
                PartsWeapon.Items[PartsWeapon.SelectedIndex] = "None";
            else
                MessageBox.Show("Select a part first.");
        }

        private void DeleteWeapon_Click(object sender, EventArgs e)
        {
            if (WeaponTree.SelectedNode == null)
            {
                MessageBox.Show("Select a weapon first.");
                return;
            }

            int Selected = WeaponTree.SelectedNode.Index;
            WeaponTree.SelectedNode = null;

            WeaponTree.Nodes.RemoveAt(Selected);
            CurrentWSG.WeaponStrings.RemoveAt(Selected);
            CurrentWSG.WeaponValues.RemoveAt(Selected);
            WeaponNames.RemoveAt(Selected);

            CurrentWSG.NumberOfWeapons--;
            TrySelectedNode(WeaponTree, Selected);
            //DoWeaponTree();
        }

        private void DuplicateWeapon_Click(object sender, EventArgs e)
        {
            if (WeaponTree.SelectedNode == null)
            {
                MessageBox.Show("Select a weapon first.");
                return;
            }

            int Selected = WeaponTree.SelectedNode.Index;

            List<string> weaponstrings = new List<string>(CurrentWSG.WeaponStrings[Selected]);
            List<int> weaponvalues = new List<int>(CurrentWSG.WeaponValues[Selected]);
            weaponvalues[2] = 0;

            CurrentWSG.WeaponStrings.Add(weaponstrings);
            CurrentWSG.WeaponValues.Add(weaponvalues);
            WeaponNames.Add(new string(WeaponNames[Selected].ToCharArray()));
            CurrentWSG.NumberOfWeapons++;
            WeaponTree.Nodes.Add((TreeNode)WeaponTree.SelectedNode.Clone());
        } // Duplicate Weapon

        private void ExportToClipboardWeapon_Click(object sender, EventArgs e)
        {
            InOutPartsBox.Clear();
            for (int Progress = 0; Progress < 14; Progress++)
            {
                if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                InOutPartsBox.AppendText((string)PartsWeapon.Items[Progress]);
            }
            InOutPartsBox.AppendText("\r\n" + RemAmmoWeapon.Value);
            InOutPartsBox.AppendText("\r\n" + QualityWeapon.Value);
            InOutPartsBox.AppendText("\r\n" + EquippedSlotWeapon.SelectedIndex);
            InOutPartsBox.AppendText("\r\n" + LevelIndexWeapon.Value);
            Clipboard.SetText(InOutPartsBox.Text + "\r\n");
        } // Export -> to Clipboard

        private void EditQualityAllWeapons_Click(object sender, EventArgs e)
        {
            int quality;
            string qualityText = Interaction.InputBox("All of the weapons in your backpack will be adjusted to the following level:", "Edit All Qualitys", "", 10, 10);
            try
            {
                quality = Convert.ToInt32(qualityText);
            }
            catch (FormatException) { return; }

            foreach (List<int> weapon in CurrentWSG.WeaponValues)
                weapon[3] = quality;

            QualityWeapon.Value = quality;
        }

        private void EditLevelAllWeapons_Click(object sender, EventArgs e)
        {
            int levelindex;
            string levelText = Interaction.InputBox("All of the weapons in your backpack will be adjusted to the following level:", "Edit All Levels", "", 10, 10);
            try
            {
                levelindex = Convert.ToInt32(levelText) + 2;
            }
            catch (FormatException) { return; }

            foreach (List<int> weapon in CurrentWSG.WeaponValues)
                weapon[3] = levelindex;

            LevelIndexWeapon.Value = levelindex;
        }

        //private void EditLevelAllWeapons_Click(object sender, EventArgs e)
        //{
        //    string tempNewLevels = Interaction.InputBox("All of the guns in your backpack will be adjusted to the following level:", "Edit All Levels", "", 10, 10);
        //    if (tempNewLevels != "" && tempNewLevels == "" + Convert.ToInt32(tempNewLevels))
        //    {
        //        foreach (List<int> item in CurrentWSG.WeaponValues)
        //            item[3] = Convert.ToInt32(tempNewLevels) + 2;
        //        LevelIndexWeapon.Value = Convert.ToInt32(tempNewLevels) + 2;
        //    }
        //}

        private void ExportToFileWeapon_Click(object sender, EventArgs e)
        {
            SaveFileDialog ToFile = new SaveFileDialog();
            ToFile.DefaultExt = "*.txt";
            ToFile.Filter = "Weapon Files(*.txt)|*.txt";
            ToFile.FileName = WeaponPartsGroup.Text + ".txt";
            if (ToFile.ShowDialog() == DialogResult.OK)
            {

                InOutPartsBox.Clear();
                for (int Progress = 0; Progress < 14; Progress++)
                {
                    if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                    InOutPartsBox.AppendText((string)PartsWeapon.Items[Progress]);
                }
                InOutPartsBox.AppendText("\r\n" + RemAmmoWeapon.Value);
                InOutPartsBox.AppendText("\r\n" + QualityWeapon.Value);
                InOutPartsBox.AppendText("\r\n" + EquippedSlotWeapon.SelectedIndex);
                InOutPartsBox.AppendText("\r\n" + LevelIndexWeapon.Value);
                InOutPartsBox.AppendText("\r\n");

                System.IO.File.WriteAllLines(ToFile.FileName, InOutPartsBox.Lines);
            }
        } // Export -> to File

        private void ExportToLockerWeapon_Click(object sender, EventArgs e)
        {
            List<string> itemparts = new List<string>();
            List<int> itemvalues = new List<int>() { 0, 5, 0, 63 };

            itemvalues[0] = (int)RemAmmoWeapon.Value;
            itemvalues[1] = QualityWeapon.Value;
            itemvalues[2] = 0;  // Drop the equipped slot
            itemvalues[3] = LevelIndexWeapon.Value;

            InOutPartsBox.Clear();

            for (int Progress = 0; Progress < 14; Progress++)
            {
                //if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                //InOutPartsBox.AppendText((string)CurrentWeaponParts.Items[Progress]);
                itemparts.Add((string)PartsWeapon.Items[Progress]);
            }

            string weaponname = WeaponTree.SelectedNode.Text;
            //            string weaponname = GetName(TitlesXml, itemparts, itemparts.Count, "PartName", "Weapon");
            //New Weapon

            List<string> iniListSectionNames = new List<string>();
            iniListSectionNames = XmlLocker.stListSectionNames();
            iniListSectionNames.TrimExcess();

            // Ok all Lockeritems now in a list

            int Occurances = 0;

            // Search the WeaponTree.Nodes[Progress].Text in the locker
            if (iniListSectionNames.Contains(weaponname))
            {
                // rename and try again until in can be added
                do
                {
                    Occurances++;
                } while (iniListSectionNames.Contains(weaponname + " (Copy " + Occurances + ")"));
                //More than one found

                //Add new Item to the xml locker
                XmlLocker.AddItem(weaponname + " (Copy " + Occurances + ")", "Weapon", itemparts, itemvalues);

                TreeNode temp = new TreeNode();
                temp.Text = weaponname + " (Copy " + Occurances + ")";
                temp.Name = weaponname + " (Copy " + Occurances + ")";
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text + " (Copy " + Occurances + ")");
            }
            else
            {
                //only one found
                XmlLocker.AddItem(weaponname, "Weapon", itemparts, itemvalues);

                XmlLocker.Reload(); // Reload the locker next time

                TreeNode temp = new TreeNode();
                temp.Text = weaponname;
                temp.Name = weaponname;
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text);
            }
        }

        private void ExportToXmlWeapons_Click(object sender, EventArgs e)
        {
            SaveFileDialog tempExport = new SaveFileDialog();
            tempExport.DefaultExt = "*.xml";
            tempExport.Filter = "WillowTree Locker(*.xml)|*.xml";

            tempExport.FileName = CurrentWSG.CharacterName + "'s Weapons.xml";
            //string ExportText = "";
            if (tempExport.ShowDialog() == DialogResult.OK)
            {
                // Create empty xml file
                XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 2;
                writer.WriteStartDocument();
                writer.WriteStartElement("INI");
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();
                writer.Close();

                XmlFile LockerSave = new XmlFile(tempExport.FileName);
                List<string> itemparts = new List<string>();
                List<int> itemvalues = new List<int>();

                for (int Progress = 0; Progress < CurrentWSG.NumberOfWeapons; Progress++)
                {
                    itemparts.Clear();
                    itemvalues.Clear();
                    for (int PartProgress = 0; PartProgress < 14; PartProgress++)
                        itemparts.Add(CurrentWSG.WeaponStrings[Progress][PartProgress]);

                    for (int PartProgress = 0; PartProgress < 4; PartProgress++)
                        itemvalues.Add(CurrentWSG.WeaponValues[Progress][PartProgress]);

                    LockerSave.AddItem(WeaponTree.Nodes[Progress].Text, "Weapon", itemparts, itemvalues);
                }
            }
        }

        public int GetWeaponDamage(string[] WeaponParts)
        {
            try
            {
                string ItemGradeFile = WeaponParts[0].Substring(0, WeaponParts[0].IndexOf(".")) + ".txt";
                string ItemGradePart = WeaponParts[0].Substring(WeaponParts[0].IndexOf(".") + 1);
                string Manufacturer = WeaponParts[1].Substring(WeaponParts[1].LastIndexOf(".") + 1);
                XmlFile ItemGrade = new XmlFile(DataPath + ItemGradeFile);

                double ExtraDamage = 0;
                double Multiplier = Conversion.Val(new XmlFile(DataPath + WeaponParts[2].Substring(0, WeaponParts[2].IndexOf(".")) + ".txt").XmlReadValue(WeaponParts[2].Substring(WeaponParts[2].IndexOf(".") + 1), "WeaponDamageFormulaMultiplier")); ;
                double Level = Conversion.Val(ItemGrade.XmlReadValue(ItemGradePart, Manufacturer + QualityWeapon.Value)) - 2;
                double Power = 1.3;
                double Offset = 9;
                for (int i = 3; i < 14; i++)
                    if (WeaponParts[i].Contains("."))
                        ExtraDamage = ExtraDamage + Conversion.Val(new XmlFile(DataPath + WeaponParts[i].Substring(0, WeaponParts[i].IndexOf(".")) + ".txt").XmlReadValue(WeaponParts[i].Substring(WeaponParts[i].IndexOf(".") + 1), "WeaponDamage"));

                //Something still slightly wrong with these calculations.  They don't match in game calcs 
                //on some weapons because of rounding issues
                double BaseDamage = Multiplier * (Math.Pow(Level, Power) + Offset);
                double BonusDamage = ExtraDamage * BaseDamage;
                int BaseDmg = (int)Math.Round(BaseDamage / 1.2);
                int BonusDmg = (int)Math.Round(BonusDamage / 1.2);
                return BaseDmg + BonusDmg;
            }
            catch { return 1337; }
        }

        public int GetWeaponDamage(string[] WeaponParts, double Itemgrade)
        {
            try
            {
                string ItemGradeFile = WeaponParts[0].Substring(0, WeaponParts[0].IndexOf(".")) + ".txt";
                string ItemGradePart = WeaponParts[0].Substring(WeaponParts[0].IndexOf(".") + 1);
                string Manufacturer = WeaponParts[1].Substring(WeaponParts[1].LastIndexOf(".") + 1);
                XmlFile ItemGrade = new XmlFile(DataPath + ItemGradeFile);
                double ExtraDamage = 0;
                double Multiplier = Conversion.Val(new XmlFile(DataPath + WeaponParts[2].Substring(0, WeaponParts[2].IndexOf(".")) + ".txt").XmlReadValue(WeaponParts[2].Substring(WeaponParts[2].IndexOf(".") + 1), "WeaponDamageFormulaMultiplier")); ;
                double Level = Itemgrade - 2;
                double Power = 1.3;
                double Offset = 9;
                for (int i = 3; i < 14; i++)
                    if (WeaponParts[i].Contains("."))
                        ExtraDamage = ExtraDamage + Conversion.Val(new XmlFile(DataPath + WeaponParts[i].Substring(0, WeaponParts[i].IndexOf(".")) + ".txt").XmlReadValue(WeaponParts[i].Substring(WeaponParts[i].IndexOf(".") + 1), "WeaponDamage"));

                //Something still slightly wrong with these calculations.  They don't match in game calcs 
                //on some weapons because of rounding issues
                double BaseDamage = Multiplier * (Math.Pow(Level, Power) + Offset);
                double BonusDamage = ExtraDamage * BaseDamage;
                int BaseDmg = (int)Math.Round(BaseDamage / 1.2);
                int BonusDmg = (int)Math.Round(BonusDamage / 1.2);
                return BaseDmg + BonusDmg;
            }
            catch
            {
                return 1337;
            }
        }

        private void ImportFromClipboardWeapon_Click(object sender, EventArgs e)
        {
            try
            {
                ImportFromTextWeapon(Clipboard.GetText());
            }
            catch
            {
                MessageBox.Show("Invalid clipboard data.  Reverting to saved values.");
                WeaponTree_AfterNodeSelect(null, null);  // reloads the saved values from the node
            }
        
        }// Import -> from Clipboard

        private void ImportFromFileWeapon_Click(object sender, EventArgs e)
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Weapon Files(*.txt)|*.txt";

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";

            if (FromFile.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ImportFromTextWeapon(System.IO.File.ReadAllText(FromFile.FileName));
                }
                catch
                {
                    MessageBox.Show("Invalid file data.  Reverting to saved values.");
                    WeaponTree_AfterNodeSelect(null, null);  // reloads the saved values from the node
                }
            }
        } // Import -> from File

        private void ImportFromTextWeapon(string Text)
        {
            InOutPartsBox.Clear();
            InOutPartsBox.Text = Text.Replace(" ", "");

            for (int Progress = 0; Progress < 14; Progress++)
            {
                ThrowExceptionIfIntString(InOutPartsBox.Lines[Progress]);
                PartsWeapon.Items[Progress] = InOutPartsBox.Lines[Progress];
            }

            RemAmmoWeapon.Value = Convert.ToInt32(InOutPartsBox.Lines[14]);
            QualityWeapon.Value = Convert.ToInt32(InOutPartsBox.Lines[15]);
            EquippedSlotWeapon.SelectedIndex = Convert.ToInt32(InOutPartsBox.Lines[16]);
            LevelIndexWeapon.Value = Convert.ToInt32(InOutPartsBox.Lines[17]);
            NameWeapon = GetWeaponNameAdvanced(InOutPartsBox.Lines);
        }

        private void ImportFromXmlWeapons_Click(object sender, EventArgs e)
        {
            OpenFileDialog tempImport = new OpenFileDialog();
            tempImport.DefaultExt = "*.xml";
            tempImport.Filter = "WillowTree Locker(*.xml)|*.xml";

            tempImport.FileName = CurrentWSG.CharacterName + "'s Weapons.xml";
            if (tempImport.ShowDialog() == DialogResult.OK)
            {
                //Ini.IniFile ImportWTL = new Ini.IniFile(tempImport.FileName);
                XmlFile ImportWTL = new XmlFile(tempImport.FileName);
                
                for (int Progress = 0; Progress < ImportWTL.stListSectionNames("Weapon").Count; Progress++)
                {
                    List<String> wpnstrings = new List<string>();
                    List<int> wpnvalues = new List<int>();
                    try 
                    {
                        for (int ProgressStrings = 0; ProgressStrings < 14; ProgressStrings++)
                        {
                            string part = ImportWTL.XmlReadValue(ImportWTL.stListSectionNames("Weapon")[Progress], "Part" + (ProgressStrings + 1));
                            ThrowExceptionIfIntString(part);
                            wpnstrings.Add(part);
                        }

                        wpnvalues.Add(Int32FromString(ImportWTL.XmlReadValue(ImportWTL.stListSectionNames("Weapon")[Progress], "RemAmmo_Quantity"),0));
                        wpnvalues.Add(Int32FromString(ImportWTL.XmlReadValue(ImportWTL.stListSectionNames("Weapon")[Progress], "Quality"),0));
                        wpnvalues.Add(0); // set equipped slot to 0
                        wpnvalues.Add(Int32FromString(ImportWTL.XmlReadValue(ImportWTL.stListSectionNames("Weapon")[Progress], "Level"),0));
                    }
                    catch
                    {
                        MessageBox.Show("Error reading XML file.  Skipping item.");
                        continue;
                    }

                    CurrentWSG.WeaponStrings.Add(wpnstrings);
                    CurrentWSG.WeaponValues.Add(wpnvalues);
                    CurrentWSG.NumberOfWeapons++;
                }
                DoWeaponTree();
            }
        }

        private void InsertFromClipboardWeapon_Click(object sender, EventArgs e) // Insert -> from Clipboard
        {
            try
            {
                InOutPartsBox.Clear();
                InOutPartsBox.Text = Clipboard.GetText();
                InOutPartsBox.Text = InOutPartsBox.Text.Replace(" ", "");

                // Create new lists
                List<string> WS = new List<string>();
                List<int> WV = new List<int>();

                try
                {

                    for (int Progress = 0; Progress < 14; Progress++)
                    {
                        ThrowExceptionIfIntString(InOutPartsBox.Lines[Progress]);
                        WS.Add(InOutPartsBox.Lines[Progress]);
                    }

                    for (int Progress = 0; Progress < 4; Progress++)
                        WV.Add(Convert.ToInt32(InOutPartsBox.Lines[Progress + 14]));
                    WV[2] = 0; // set equipped slot to 0
                }
                catch
                {
                    MessageBox.Show("Invalid file data or unable to read file.");
                    return;
                }
                CurrentWSG.WeaponStrings.Add(WS);
                CurrentWSG.WeaponValues.Add(WV);
                CurrentWSG.NumberOfWeapons++;

                TreeNode TempNode = new TreeNode();
                TempNode.Text = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1]);
                WeaponTree.Nodes.Add(TempNode);
                //DoWeaponTree();
            }
            catch { }
        }

        private void InsertFromFileWeapon_Click(object sender, EventArgs e) // Insert -> from File
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Weapon Files(*.txt)|*.txt";

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";

            if (FromFile.ShowDialog() == DialogResult.OK)
            {

                InOutPartsBox.Clear();
                InOutPartsBox.Text = System.IO.File.ReadAllText(FromFile.FileName);

                List<string> wpnstrings = new List<string>();
                List<int> wpnvalues = new List<int>();

                try
                {
                    for (int Progress = 0; Progress < 14; Progress++)
                    {
                        ThrowExceptionIfIntString(InOutPartsBox.Lines[Progress]);
                        wpnstrings.Add(InOutPartsBox.Lines[Progress]);
                    }
                    for (int Progress = 0; Progress < 4; Progress++)
                        wpnvalues.Add(Convert.ToInt32(InOutPartsBox.Lines[Progress + 14]));
                    wpnvalues[2] = 0; // set equipped slot to none
                }
                catch
                {
                    MessageBox.Show("Invalid file data or unable to read file.");
                    return;
                }

                CurrentWSG.WeaponStrings.Add(wpnstrings);
                CurrentWSG.WeaponValues.Add(wpnvalues);
                CurrentWSG.NumberOfWeapons++;

                TreeNode TempNode = new TreeNode();
                TempNode.Text = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1]);
                WeaponTree.Nodes.Add(TempNode);
                //DoWeaponTree();
            }
        }

        private void InsertFromFilesWeapons_Click(object sender, EventArgs e)
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Weapon Files(*.txt)|*.txt";
            FromFile.Multiselect = true;

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";

            if (FromFile.ShowDialog() == DialogResult.OK)
            {
                foreach (String file in FromFile.FileNames)
                {
                    InOutPartsBox.Clear();
                    InOutPartsBox.Text = System.IO.File.ReadAllText(file);

                    // Create new lists
                    List<string> wpnstrings = new List<string>();
                    List<int> wpnvalues = new List<int>();

                    try
                    {
                        for (int Progress = 0; Progress < 14; Progress++)
                        {
                            ThrowExceptionIfIntString(InOutPartsBox.Lines[Progress]);
                            wpnstrings.Add(InOutPartsBox.Lines[Progress]);
                        }

                        for (int Progress = 0; Progress < 4; Progress++)
                            wpnvalues.Add(Convert.ToInt32(InOutPartsBox.Lines[Progress + 14]));
                        wpnvalues[2] = 0; // set equipped slot to none
                    }
                    catch
                    {
                        MessageBox.Show("Invalid file data or unable to read file \"" + file + "\".");
                        continue;
                    }
                    CurrentWSG.WeaponStrings.Add(wpnstrings);
                    CurrentWSG.WeaponValues.Add(wpnvalues);
                    CurrentWSG.NumberOfWeapons++;

                    TreeNode TempNode = new TreeNode();
                    TempNode.Text = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1]);
                    WeaponTree.Nodes.Add(TempNode);
                    //DoWeaponTree();

                }
            }

        }

        private void PartCategoriesWeapon_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            PartInfoWeapon.Clear();
            try
            {
                // Read ALL subsections of a given XML section
                // File: (DataPath + PartCategories.SelectedNode.Parent.Text + ".txt")
                XmlFile Category = new XmlFile(DataPath + PartCategoriesWeapon.SelectedNode.Parent.Text + ".txt");

                // XML Section: PartCategories.SelectedNode.Text
                List<string> xmlSection = Category.XmlReadSection(PartCategoriesWeapon.SelectedNode.Text);

                PartInfoWeapon.Lines = xmlSection.ToArray();

            }
            catch { }
        }

        private void PartCategoriesWeapon_NodeDoubleClick(object sender, MouseEventArgs e)
        {
            if (PartsWeapon.SelectedItem != null && PartCategoriesWeapon.SelectedNode.FirstNode == null)
            {
                PartsWeapon.Items[PartsWeapon.SelectedIndex] = PartCategoriesWeapon.SelectedNode.Parent.Text + "." + PartCategoriesWeapon.SelectedNode.Text;
            }

        }

        private void PartsWeapon_DoubleClick(object sender, EventArgs e)
        {
            //Interaction.InputBox TempBox = new Interaction.InputBox("Enter a new part", "Manual Edit", (string)CurrentWeaponParts.SelectedItem, 0, 0);
            //string test = Interaction.InputBox("Enter a new part", "Manual Edit", (string)CurrentWeaponParts.SelectedItem, 10, 10);
            string tempManualPart = Interaction.InputBox("Enter a new part", "Manual Edit", (string)PartsWeapon.SelectedItem, 10, 10);
            if (tempManualPart != "")
                PartsWeapon.Items[PartsWeapon.SelectedIndex] = tempManualPart;
        }

        private void PartsWeapon_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (PartsWeapon.SelectedIndex == -1)
                return;

            string part = (string)PartsWeapon.Items[PartsWeapon.SelectedIndex];
            try
            {
                PartCategoriesWeapon.SelectedNode = PartCategoriesWeapon.Nodes[part.Before('.')].Nodes[part.After('.')];
            }
            catch { }
        }

        private void NewWeapon_Click(object sender, EventArgs e)
        {
            try
            {
                CurrentWSG.NumberOfWeapons++;
                CurrentWSG.WeaponStrings.Add(new List<string>());
                CurrentWSG.WeaponValues.Add(new List<int>());
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Item Grade");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Manufacturer");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Weapon Type");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Body");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Grip");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Mag");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Barrel");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Sight");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Stock");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Action");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Accessory");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Material");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Prefix");
                CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add("Title");
                CurrentWSG.WeaponValues[(CurrentWSG.NumberOfWeapons - 1)].Add(0);
                CurrentWSG.WeaponValues[(CurrentWSG.NumberOfWeapons - 1)].Add(0);
                CurrentWSG.WeaponValues[(CurrentWSG.NumberOfWeapons - 1)].Add(0);
                CurrentWSG.WeaponValues[(CurrentWSG.NumberOfWeapons - 1)].Add(0);

                TreeNode TempNode = new TreeNode();
                TempNode.Text = "New Weapon";
                WeaponTree.Nodes.Add(TempNode);
                //DoWeaponTree();
            }
            catch { }
        }

        private void SaveChangesWeapon_Click(object sender, EventArgs e)
        {
            try
            {
                int Selected = WeaponTree.SelectedNode.Index; ;

                for (int Progress = 0; Progress < 14; Progress++)
                    CurrentWSG.WeaponStrings[WeaponTree.SelectedNode.Index][Progress] = (string)PartsWeapon.Items[Progress];
                CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][0] = (int)RemAmmoWeapon.Value;

                CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][1] = (int)QualityWeapon.Value;
                CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][3] = (int)LevelIndexWeapon.Value;

                CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][2] = EquippedSlotWeapon.SelectedIndex;
                //DoWeaponTree();

                WeaponTree.SelectedNode.Text = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[WeaponTree.SelectedNode.Index]);
            }
            catch { }
        } // Save Changes

        private void WeaponInfo_Click(object sender, EventArgs e)
        {
            string[] Parts = new string[14];

            int prog = 0;
            foreach (string i in PartsWeapon.Items)
            {
                Parts[prog] = i;
                prog = prog + 1;
            }
            string WeaponInfo;
            DamageText.Text = "Expected Weapon Damage: " + GetWeaponDamage(Parts);
            if (LevelIndexWeapon.Value > 0)
                WeaponInfo = "Expected Damage: " + GetWeaponDamage(Parts, LevelIndexWeapon.Value);
            else
                WeaponInfo = "Expected Damage: " + GetWeaponDamage(Parts);
            if (GetExtraStats(Parts, "TechLevelIncrease") != 0)
                WeaponInfo = WeaponInfo + "\r\nElemental Tech Level: " + GetExtraStats(Parts, "TechLevelIncrease");
            if (GetExtraStats(Parts, "WeaponDamage") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "WeaponDamage") + "% Damage";
            if (GetExtraStats(Parts, "WeaponFireRate") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "WeaponFireRate") + "% Rate of Fire";
            if (GetExtraStats(Parts, "WeaponCritBonus") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "WeaponCritBonus") + "% Critical Damage";
            if (GetExtraStats(Parts, "WeaponReloadSpeed") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "WeaponReloadSpeed") + "% Reload Speed";
            if (GetExtraStats(Parts, "WeaponSpread") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "WeaponSpread") + "% Spread";
            if (GetExtraStats(Parts, "MaxAccuracy") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "MaxAccuracy") + "% Max Accuracy";
            if (GetExtraStats(Parts, "MinAccuracy") != 0)
                WeaponInfo = WeaponInfo + "\r\n" + GetExtraStats(Parts, "MinAccuracy") + "% Min Accuracy";
            MessageBox.Show(WeaponInfo);
        }

        private void WeaponTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                PartsWeapon.Items.Clear();
                WeaponPartsGroup.Text = WeaponTree.SelectedNode.Text;

//                    for (int ndcnt = 0; ndcnt < PartCategories.Nodes.Count; ndcnt++)
//                        PartCategories.Nodes[ndcnt].Style = elementStyle15;

                for (int build_list = 0; build_list < 14; build_list++)
                {
                    string curWeaponpart = CurrentWSG.WeaponStrings[WeaponTree.SelectedNode.Index][build_list];
                    PartsWeapon.Items.Add(curWeaponpart);
                    // highlight the used partfamilies in the partscategories tree
                    if (curWeaponpart.Contains('.'))
                    {
                        string curWeaponpartclass = curWeaponpart.Substring(0, curWeaponpart.IndexOf('.'));
                        for (int ndcnt = 0; ndcnt < PartCategoriesWeapon.Nodes.Count; ndcnt++)
                        {
                            if (PartCategoriesWeapon.Nodes[ndcnt].Name == curWeaponpartclass)
                            {
//                              WeaponPartsSelector.Nodes[ndcnt].Style = elementStyle16;
                                break;
                            }
                        }
                    }
                }

                try
                {
                    RemAmmoWeapon.Value = CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][0];
                }
                catch { }
                //Set Itemgrade before Quality -> Level will display correct
                try
                {
                    LevelIndexWeapon.Value = CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][3];
                }
                catch { }
                try
                {
                    QualityWeapon.Value = CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][1];
                }
                catch { }

                if (CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][2] == 0) EquippedSlotWeapon.SelectedItem = "Unequipped";
                else if (CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][2] == 1) EquippedSlotWeapon.SelectedItem = "Slot 1 (Up)";
                else if (CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][2] == 2) EquippedSlotWeapon.SelectedItem = "Slot 2 (Down)";
                else if (CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][2] == 3) EquippedSlotWeapon.SelectedItem = "Slot 3 (Left)";
                else if (CurrentWSG.WeaponValues[WeaponTree.SelectedNode.Index][2] > 3) EquippedSlotWeapon.SelectedItem = "Slot 4 (Right)";
            }
            catch { }
        }

        public class WeaponInfo
        {
            public string Manufacturer;
            public int BaseLevel;
            public int ItemGrade;
            public string Name;

            double Multiplier;

            public WeaponInfo(string[] Parts, int[] Values)
            {
                ItemGrade = Convert.ToInt32(Values[1]);
                Manufacturer = GetPartAttribute(Parts[1], "Manufacturer");

                string BaseLevelText = GetPartAttribute(Parts[0], Manufacturer + ItemGrade);
                BaseLevel = (BaseLevelText == "" ? 0 : Convert.ToInt32(BaseLevelText));

                string MultiplierText = GetPartAttribute(Parts[2], "WeaponDamageFormulaMultiplier");
                Multiplier = Conversion.Val(MultiplierText);

                for (int i = 3; i < 14; i++)
                {

                }
            }
        }
        #endregion
        #region <<<<< QUEST PANEL >>>>>

        public bool Clicked = false; //Goes with the quest stuff. Really...ineffective.

        private void Objectives_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (QuestTree.SelectedNode.Name == "PT1" && Clicked == true)
                ObjectiveValue.Value = CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, Objectives.SelectedIndex + 4];
            else if (QuestTree.SelectedNode.Name == "PT2" && Clicked == true)
                ObjectiveValue.Value = CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, Objectives.SelectedIndex + 4];
        }

        private void ObjectiveValue_ValueChanged(object sender, EventArgs e)
        {
            if (Objectives.Items.Count > 0)
                if (QuestTree.SelectedNode.Name == "PT1" && Clicked == true)
                    CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, Objectives.SelectedIndex + 4] = (int)ObjectiveValue.Value;
                else if (QuestTree.SelectedNode.Name == "PT2" && Clicked == true)
                    CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, Objectives.SelectedIndex + 4] = (int)ObjectiveValue.Value;
        }

        private void QuestList_SelectedIndexChanged(object sender, EventArgs e)
        {
            int SelectedItem = QuestList.SelectedIndex;
            NewQuest.HideDropDown();
            try
            {
                //Ini.IniFile Quests = new Ini.IniFile(DataPath + "Quests.ini");
                XmlFile Quests = new XmlFile(DataPath + "Quests.ini");
                if (QuestTree.SelectedNode.Name == "PT1" || QuestTree.SelectedNode == QuestTree.Nodes[0])
                {
                    int TotalObjectives = 0;
                    CurrentWSG.TotalPT1Quests = CurrentWSG.TotalPT1Quests + 1;
                    ResizeArrayLarger(ref CurrentWSG.PT1Strings, CurrentWSG.TotalPT1Quests);
                    ResizeArrayLarger(ref CurrentWSG.PT1Values, CurrentWSG.TotalPT1Quests, 9);
                    ResizeArrayLarger(ref CurrentWSG.PT1Subfolders, CurrentWSG.TotalPT1Quests, 5);
                    CurrentWSG.PT1Strings[CurrentWSG.TotalPT1Quests - 1] = Quests.stListSectionNames()[SelectedItem];
                    CurrentWSG.PT1Values[CurrentWSG.TotalPT1Quests - 1, 0] = 1;
                    for (int Progress = 0; Progress < 5; Progress++)
                        if (Quests.XmlReadValue(Quests.stListSectionNames()[SelectedItem], "Objectives" + Progress) == "") break;
                        else TotalObjectives = Progress + 1;
                    CurrentWSG.PT1Values[CurrentWSG.TotalPT1Quests - 1, 3] = TotalObjectives;
                    for (int Progress = 0; Progress < 5; Progress++)
                        CurrentWSG.PT1Subfolders[CurrentWSG.TotalPT1Quests - 1, Progress] = "None";

                    DoQuestTree();
                    QuestTree.SelectedNode = QuestTree.Nodes[0].Nodes[CurrentWSG.TotalPT1Quests - 1];
                }
                if (QuestTree.SelectedNode.Name == "PT2" || QuestTree.SelectedNode.Text == "Playthrough 2 Quests")
                {
                    int TotalObjectives = 0;
                    CurrentWSG.TotalPT2Quests = CurrentWSG.TotalPT2Quests + 1;
                    ResizeArrayLarger(ref CurrentWSG.PT2Strings, CurrentWSG.TotalPT2Quests);
                    ResizeArrayLarger(ref CurrentWSG.PT2Values, CurrentWSG.TotalPT2Quests, 9);
                    ResizeArrayLarger(ref CurrentWSG.PT2Subfolders, CurrentWSG.TotalPT2Quests, 5);
                    CurrentWSG.PT2Strings[CurrentWSG.TotalPT2Quests - 1] = Quests.stListSectionNames()[SelectedItem];
                    CurrentWSG.PT2Values[CurrentWSG.TotalPT2Quests - 1, 0] = 1;
                    for (int Progress = 0; Progress < 5; Progress++)
                        if (Quests.XmlReadValue(Quests.stListSectionNames()[SelectedItem], "Objectives[" + Progress + "]") == "") break;
                        else TotalObjectives = Progress + 1;
                    CurrentWSG.PT2Values[CurrentWSG.TotalPT2Quests - 1, 3] = TotalObjectives;
                    for (int Progress = 0; Progress < 5; Progress++)
                        CurrentWSG.PT2Subfolders[CurrentWSG.TotalPT2Quests - 1, Progress] = "None";

                    DoQuestTree();
                    QuestTree.SelectedNode = QuestTree.Nodes[1].Nodes[CurrentWSG.TotalPT2Quests - 1];
                }
            }
            catch { }
        }

        private void QuestProgress_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                XmlFile Quests = new XmlFile(DataPath + "Quests.ini");
                if (QuestTree.SelectedNode.Name == "PT1" && Clicked == true)
                {
                    if (CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] == 4 && QuestProgress.SelectedIndex < 3)
                    {
                        Objectives.Items.Clear();
                        int TotalObjectives = 0;

                        //string curTxt;
                        for (int Progress = 0; Progress < 5; Progress++)
                        {
                            //curTxt = Quests.IniReadValue(QuestString.Text, "Objectives[" + Progress + "]");
                            if (Quests.XmlReadValue(QuestString.Text, "Objectives" + Progress) == "") break;
                            else TotalObjectives = Progress + 1;
                        }
                        CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 3] = TotalObjectives;
                        for (int Progress = 0; Progress < 5; Progress++)
                            CurrentWSG.PT1Subfolders[QuestTree.SelectedNode.Index, Progress] = "None";
                        NumberOfObjectives.Value = TotalObjectives;
                        if (TotalObjectives > 0)
                            for (int Progress = 0; Progress < TotalObjectives; Progress++)
                                Objectives.Items.Add(Quests.XmlReadValue(QuestString.Text, "Objectives" + Progress));
                        ObjectiveValue.Value = 0;
                        CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] = QuestProgress.SelectedIndex;
                        CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 3] = TotalObjectives;
                        for (int Progress = 0; Progress < 5; Progress++)
                            CurrentWSG.PT1Subfolders[QuestTree.SelectedNode.Index, Progress] = "None";
                    }
                    else if (CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] != 4 && QuestProgress.SelectedIndex == 3)
                    {
                        Objectives.Items.Clear();
                        CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] = 4;
                        CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 3] = 0;
                    }
                    else if (CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] != 4 && QuestProgress.SelectedIndex < 3)
                        CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] = QuestProgress.SelectedIndex;
                }
                else if (QuestTree.SelectedNode.Name == "PT2" && Clicked == true)
                {
                    if (CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] == 4 && QuestProgress.SelectedIndex < 3)
                    {
                        Objectives.Items.Clear();
                        int TotalObjectives = 0;
                        for (int Progress = 0; Progress < 5; Progress++)
                            if (Quests.XmlReadValue(QuestString.Text, "Objectives" + Progress) == "") break;
                            else TotalObjectives = Progress + 1;
                        CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 3] = TotalObjectives;
                        for (int Progress = 0; Progress < 5; Progress++)
                            CurrentWSG.PT2Subfolders[QuestTree.SelectedNode.Index, Progress] = "None";
                        NumberOfObjectives.Value = TotalObjectives;
                        if (NumberOfObjectives.Value > 0)
                            for (int Progress = 0; Progress < NumberOfObjectives.Value; Progress++)
                                Objectives.Items.Add(Quests.XmlReadValue(QuestString.Text, "Objectives" + Progress));
                        ObjectiveValue.Value = 0;
                        CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] = QuestProgress.SelectedIndex;
                        CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 3] = TotalObjectives;
                    }
                    else if (CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] != 4 && QuestProgress.SelectedIndex == 3)
                    {
                        Objectives.Items.Clear();
                        CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] = 4;
                        CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 3] = 0;
                        //for (int Progress = 0; Progress < 5; Progress++)
                        //    CurrentWSG.PT2Subfolders[QuestTree.SelectedNode.Index, Progress] = "None";
                    }
                    else if (CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] != 4 && QuestProgress.SelectedIndex < 3)
                        CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] = QuestProgress.SelectedIndex;

                }
            }
            catch { }
        }

        private void QuestProgress_Click(object sender, EventArgs e)
        {
            Clicked = true;
        }

        private void QuestTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            Clicked = false;
            try
            {
                SelectedQuestGroup.Text = QuestTree.SelectedNode.Text;
                //if (QuestTree.SelectedNode.Parent.Text == "Playthrough 1 Quests" && QuestTree.SelectedNode.FirstNode == null)

                //else if (QuestTree.SelectedNode.Parent.Text == "Playthrough 2 Quests" && QuestTree.SelectedNode.FirstNode == null)
                if (QuestTree.SelectedNode.Name == "PT1")
                {

                    QuestString.Text = CurrentWSG.PT1Strings[QuestTree.SelectedNode.Index];
                    if (CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0] > 2)
                        QuestProgress.SelectedIndex = 3;
                    else QuestProgress.SelectedIndex = CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 0];
                    NumberOfObjectives.Value = CurrentWSG.PT1Values[QuestTree.SelectedNode.Index, 3];
                    Objectives.Items.Clear();
                    XmlFile Quest = new XmlFile(DataPath + "Quests.ini");
                    if (NumberOfObjectives.Value > 0)
                        for (int Progress = 0; Progress < NumberOfObjectives.Value; Progress++)
                            Objectives.Items.Add(Quest.XmlReadValue(QuestString.Text, "Objectives" + Progress));
                    ObjectiveValue.Value = 0;
                    QuestSummary.Text = Quest.XmlReadValue(QuestString.Text, "MissionSummary");
                    QuestDescription.Text = Quest.XmlReadValue(QuestString.Text, "MissionDescription");
                }
                else if (QuestTree.SelectedNode.Name == "PT2")
                {
                    QuestString.Text = CurrentWSG.PT2Strings[QuestTree.SelectedNode.Index];
                    if (CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0] > 2)
                        QuestProgress.SelectedIndex = 3;
                    else QuestProgress.SelectedIndex = CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 0];
                    NumberOfObjectives.Value = CurrentWSG.PT2Values[QuestTree.SelectedNode.Index, 3];
                    Objectives.Items.Clear();
                    XmlFile Quest = new XmlFile(DataPath + "Quests.ini");
                    if (NumberOfObjectives.Value > 0)
                        for (int Progress = 0; Progress < NumberOfObjectives.Value; Progress++)
                            Objectives.Items.Add(Quest.XmlReadValue(QuestString.Text, "Objectives" + Progress));
                    ObjectiveValue.Value = 0;
                    QuestSummary.Text = Quest.XmlReadValue(QuestString.Text, "MissionSummary");
                    QuestDescription.Text = Quest.XmlReadValue(QuestString.Text, "MissionDescription");
                }
            }
            catch { QuestString.Text = ""; Objectives.Items.Clear(); NumberOfObjectives.Value = 0; ObjectiveValue.Value = 0; QuestProgress.SelectedIndex = 0; }
        }

        private void DeleteQuest_Click(object sender, EventArgs e)
        {
            try
            {
                int Selected = QuestTree.SelectedNode.Index; ;
                if (QuestTree.SelectedNode.Name == "PT1")
                {
                    if (QuestTree.SelectedNode.Text != "Fresh Off The Bus" || MultipleIntroStateSaver(1) == true)
                    {
                        Selected = QuestTree.SelectedNode.Index;
                        CurrentWSG.TotalPT1Quests = CurrentWSG.TotalPT1Quests - 1;
                        for (int Position = Selected; Position < CurrentWSG.TotalPT1Quests; Position++)
                        {
                            CurrentWSG.PT1Strings[Position] = CurrentWSG.PT1Strings[Position + 1];
                            for (int Progress = 0; Progress < 4; Progress++)
                                CurrentWSG.PT1Values[Position, Progress] = CurrentWSG.PT1Values[Position + 1, Progress];
                            for (int Progress = 0; Progress < 5; Progress++)
                                CurrentWSG.PT1Subfolders[Position, Progress] = CurrentWSG.PT1Subfolders[Position + 1, Progress];
                        }
                        ResizeArraySmaller(ref CurrentWSG.PT1Strings, CurrentWSG.TotalPT1Quests);
                        ResizeArraySmaller(ref CurrentWSG.PT1Subfolders, CurrentWSG.TotalPT1Quests, 5);
                        ResizeArraySmaller(ref CurrentWSG.PT1Values, CurrentWSG.TotalPT1Quests, 9);
                        DoQuestTree();
                        QuestTree.SelectedNode = QuestTree.Nodes[0].Nodes[Selected];
                    }
                    else if (MultipleIntroStateSaver(1) == false)
                        MessageBox.Show("You must have the default quest.");
                }
                else if (QuestTree.SelectedNode.Name == "PT2")
                {
                    if (QuestTree.SelectedNode.Text != "Fresh Off The Bus" || MultipleIntroStateSaver(2) == true)
                    {
                        Selected = QuestTree.SelectedNode.Index;
                        CurrentWSG.TotalPT2Quests = CurrentWSG.TotalPT2Quests - 1;
                        for (int Position = Selected; Position < CurrentWSG.TotalPT2Quests; Position++)
                        {
                            CurrentWSG.PT2Strings[Position] = CurrentWSG.PT2Strings[Position + 1];
                            for (int Progress = 0; Progress < 4; Progress++)
                                CurrentWSG.PT2Values[Position, Progress] = CurrentWSG.PT2Values[Position + 1, Progress];
                            for (int Progress = 0; Progress < 5; Progress++)
                                CurrentWSG.PT2Subfolders[Position, Progress] = CurrentWSG.PT2Subfolders[Position + 1, Progress];
                        }
                        ResizeArraySmaller(ref CurrentWSG.PT2Strings, CurrentWSG.TotalPT2Quests);
                        ResizeArraySmaller(ref CurrentWSG.PT2Subfolders, CurrentWSG.TotalPT2Quests, 5);
                        ResizeArraySmaller(ref CurrentWSG.PT2Values, CurrentWSG.TotalPT2Quests, 9);

                        DoQuestTree();

                        try
                        {
                            QuestTree.SelectedNode = QuestTree.Nodes[1].Nodes[Selected];
                        }
                        catch { }
                    }
                    else if (MultipleIntroStateSaver(2) == false)
                        MessageBox.Show("You must have the default quest.");
                }
            }
            catch { }
        }

        private void ExportToFileQuests_Click(object sender, EventArgs e)
        {
            try
            {
                if (QuestTree.SelectedNode.Name == "PT2")
                {
                    SaveFileDialog tempExport = new SaveFileDialog();
                    //string ExportText = "";
                    tempExport.DefaultExt = "*.quests";
                    tempExport.Filter = "Quest Data(*.quests)|*.quests";

                    tempExport.FileName = CurrentWSG.CharacterName + "'s PT2 Quests.quests";

                    if (tempExport.ShowDialog() == DialogResult.OK)
                    {
                        // Create empty xml file
                        XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                        writer.Formatting = Formatting.Indented;
                        writer.Indentation = 2;
                        writer.WriteStartDocument();
                        writer.WriteStartElement("INI");
                        writer.WriteEndElement();
                        writer.WriteEndDocument();
                        writer.Flush();
                        writer.Close();

                        XmlFile Quests = new XmlFile(tempExport.FileName);
                        List<string> subsectionnames = new List<string>();
                        List<string> subsectionvalues = new List<string>();

                        for (int Progress = 0; Progress < CurrentWSG.TotalPT2Quests; Progress++)
                        {
                            subsectionnames.Clear();
                            subsectionvalues.Clear();

                            subsectionnames.Add("Progress");
                            subsectionnames.Add("DLCValue1");
                            subsectionnames.Add("DLCValue2");
                            subsectionnames.Add("Objectives");

                            for (int i = 0; i < 4; i++)
                                subsectionvalues.Add(CurrentWSG.PT2Values[Progress, i].ToString());

                            //ExportText = ExportText + "[" + CurrentWSG.PT2Strings[Progress] + "]\r\nProgress=" + CurrentWSG.PT2Values[Progress, 0] + "\r\nDLCValue1=" + CurrentWSG.PT2Values[Progress, 1] + "\r\nDLCValue2=" + CurrentWSG.PT2Values[Progress, 2] + "\r\nObjectives=" + CurrentWSG.PT2Values[Progress, 3] + "\r\n";
                            for (int Folders = 0; Folders < CurrentWSG.PT2Values[Progress, 3]; Folders++)
                            {
                                subsectionnames.Add("FolderName" + Folders);
                                subsectionvalues.Add(CurrentWSG.PT2Subfolders[Progress, Folders]);
                                subsectionnames.Add("FolderValue" + Folders);
                                subsectionvalues.Add(CurrentWSG.PT2Values[Progress, Folders + 4].ToString());

                                //ExportText = ExportText + "FolderName" + Folders + "=" + CurrentWSG.PT2Subfolders[Progress, Folders] + "\r\nFolderValue" + Folders + "=" + CurrentWSG.PT2Values[Progress, Folders + 4] + "\r\n";
                            }
                            Quests.AddSection(CurrentWSG.PT2Strings[Progress], subsectionnames, subsectionvalues);
                        }
                    }
                }
                else if (QuestTree.SelectedNode.Name == "PT1")
                {
                    SaveFileDialog tempExport = new SaveFileDialog();
                    //string ExportText = "";
                    tempExport.DefaultExt = "*.quests";
                    tempExport.Filter = "Quest Data(*.quests)|*.quests";

                    tempExport.FileName = CurrentWSG.CharacterName + "'s PT1 Quests.quests";

                    if (tempExport.ShowDialog() == DialogResult.OK)
                    {
                        // Create empty xml file
                        XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                        writer.Formatting = Formatting.Indented;
                        writer.Indentation = 2;
                        writer.WriteStartDocument();
                        writer.WriteStartElement("INI");
                        writer.WriteEndElement();
                        writer.WriteEndDocument();
                        writer.Flush();
                        writer.Close();

                        XmlFile Quests = new XmlFile(tempExport.FileName);
                        List<string> subsectionnames = new List<string>();
                        List<string> subsectionvalues = new List<string>();

                        for (int Progress = 0; Progress < CurrentWSG.TotalPT1Quests; Progress++)
                        {
                            subsectionnames.Clear();
                            subsectionvalues.Clear();

                            subsectionnames.Add("Progress");
                            subsectionnames.Add("DLCValue1");
                            subsectionnames.Add("DLCValue2");
                            subsectionnames.Add("Objectives");

                            for (int i = 0; i < 4; i++)
                                subsectionvalues.Add(CurrentWSG.PT1Values[Progress, i].ToString());
                            //ExportText = ExportText + "[" + CurrentWSG.PT1Strings[Progress] + "]\r\nProgress=" + CurrentWSG.PT1Values[Progress, 0] + "\r\nDLCValue1=" + CurrentWSG.PT1Values[Progress, 1] + "\r\nDLCValue2=" + CurrentWSG.PT1Values[Progress, 2] + "\r\nObjectives=" + CurrentWSG.PT1Values[Progress, 3] + "\r\n";

                            for (int Folders = 0; Folders < CurrentWSG.PT1Values[Progress, 3]; Folders++)
                            {
                                subsectionnames.Add("FolderName" + Folders);
                                subsectionvalues.Add(CurrentWSG.PT1Subfolders[Progress, Folders]);
                                subsectionnames.Add("FolderValue" + Folders);
                                subsectionvalues.Add(CurrentWSG.PT1Values[Progress, Folders + 4].ToString());

                                //ExportText = ExportText + "FolderName" + Folders + "=" + CurrentWSG.PT1Subfolders[Progress, Folders] + "\r\nFolderValue" + Folders + "=" + CurrentWSG.PT1Values[Progress, Folders + 4] + "\r\n";
                            }
                            Quests.AddSection(CurrentWSG.PT1Strings[Progress], subsectionnames, subsectionvalues);
                        }
                    }
                }


            }
            catch { MessageBox.Show("Select a playthrough to extract first."); }

        }

        private void ImportFromFileQuests_Click(object sender, EventArgs e)
        {
            try
            {
                if (QuestTree.SelectedNode.Name == "PT2")
                {
                    OpenFileDialog tempImport = new OpenFileDialog();
                    tempImport.DefaultExt = "*.quests";
                    tempImport.Filter = "Quest Data(*.quests)|*.quests";

                    tempImport.FileName = CurrentWSG.CharacterName + "'s PT2 Quests.quests";
                    if (tempImport.ShowDialog() == DialogResult.OK)
                    {
                        //Ini.IniFile ImportQuests = new Ini.IniFile(tempImport.FileName);
                        XmlFile ImportQuests = new XmlFile(tempImport.FileName);
                        string[] TempQuestStrings = new string[ImportQuests.stListSectionNames().Count];
                        int[,] TempQuestValues = new int[ImportQuests.stListSectionNames().Count, 10];
                        string[,] TempQuestSubfolders = new string[ImportQuests.stListSectionNames().Count, 7];
                        for (int Progress = 0; Progress < ImportQuests.stListSectionNames().Count; Progress++)
                        {
                            TempQuestStrings[Progress] = ImportQuests.stListSectionNames()[Progress];
                            TempQuestValues[Progress, 0] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "Progress"));
                            TempQuestValues[Progress, 1] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "DLCValue1"));
                            TempQuestValues[Progress, 2] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "DLCValue2"));
                            TempQuestValues[Progress, 3] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "Objectives"));
                            for (int Folders = 0; Folders < TempQuestValues[Progress, 3]; Folders++)
                            {
                                TempQuestValues[Progress, Folders + 4] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "FolderValue" + Folders));
                                TempQuestSubfolders[Progress, Folders] = ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "FolderName" + Folders);
                            }
                        }
                        CurrentWSG.PT2Strings = TempQuestStrings;
                        CurrentWSG.PT2Values = TempQuestValues;
                        CurrentWSG.PT2Subfolders = TempQuestSubfolders;
                        CurrentWSG.TotalPT2Quests = ImportQuests.stListSectionNames().Count;
                        DoQuestTree();
                    }
                }
                else if (QuestTree.SelectedNode.Name == "PT1")
                {
                    OpenFileDialog tempImport = new OpenFileDialog();
                    tempImport.DefaultExt = "*.quests";
                    tempImport.Filter = "Quest Data(*.quests)|*.quests";

                    tempImport.FileName = CurrentWSG.CharacterName + "'s PT1 Quests.quests";
                    if (tempImport.ShowDialog() == DialogResult.OK)
                    {
                        XmlFile ImportQuests = new XmlFile(tempImport.FileName);
                        string[] TempQuestStrings = new string[ImportQuests.stListSectionNames().Count];
                        int[,] TempQuestValues = new int[ImportQuests.stListSectionNames().Count, 10];
                        string[,] TempQuestSubfolders = new string[ImportQuests.stListSectionNames().Count, 7];
                        for (int Progress = 0; Progress < ImportQuests.stListSectionNames().Count; Progress++)
                        {
                            TempQuestStrings[Progress] = ImportQuests.stListSectionNames()[Progress];
                            TempQuestValues[Progress, 0] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "Progress"));
                            TempQuestValues[Progress, 1] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "DLCValue1"));
                            TempQuestValues[Progress, 2] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "DLCValue2"));
                            TempQuestValues[Progress, 3] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "Objectives"));
                            for (int Folders = 0; Folders < TempQuestValues[Progress, 3]; Folders++)
                            {
                                TempQuestValues[Progress, Folders + 4] = Convert.ToInt32(ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "FolderValue" + Folders));
                                TempQuestSubfolders[Progress, Folders] = ImportQuests.XmlReadValue(ImportQuests.stListSectionNames()[Progress], "FolderName" + Folders);
                            }
                        }
                        CurrentWSG.PT1Strings = TempQuestStrings;
                        CurrentWSG.PT1Values = TempQuestValues;
                        CurrentWSG.PT1Subfolders = TempQuestSubfolders;
                        CurrentWSG.TotalPT1Quests = ImportQuests.stListSectionNames().Count;
                        DoQuestTree();
                    }
                }
            }
            catch { MessageBox.Show("Select a playthrough to replace first."); }




        }

        private void ImportFromSaveQuests_Click(object sender, EventArgs e)
        {
            OpenFileDialog tempOpen = new OpenFileDialog();
            tempOpen.DefaultExt = "*.sav";
            tempOpen.Filter = "WillowSaveGame(*.sav)|*.sav";

            if (tempOpen.ShowDialog() == DialogResult.OK)
            {
                WillowSaveGame OtherSave = new WillowSaveGame();

                try
                {
                    OtherSave.LoadWSG(tempOpen.FileName);
                }
                catch { return; }

                // Note that when you set arrays equal to one another like this it doesn't copy
                // the array elements, only the pointer to the array.  This only works because
                // OtherSave will be disposed of right away and not modify the values.  If OtherSave
                // was being used actively then a new set of arrays would have to be created and the
                // data copied to them with Array.Copy, otherwise both saves would be linked to the 
                // same array in memory and corrupt each other's data.
                CurrentWSG.TotalPT1Quests = OtherSave.TotalPT1Quests;
                CurrentWSG.PT1Strings = OtherSave.PT1Strings;
                CurrentWSG.PT1Values = OtherSave.PT1Values;
                CurrentWSG.PT1Subfolders = OtherSave.PT1Subfolders;
                CurrentWSG.UnknownPT1QuestValue = OtherSave.UnknownPT1QuestValue;

                CurrentWSG.TotalPT2Quests = OtherSave.TotalPT2Quests;
                CurrentWSG.PT2Strings = OtherSave.PT2Strings;
                CurrentWSG.PT2Values = OtherSave.PT2Values;
                CurrentWSG.PT1Subfolders = OtherSave.PT1Subfolders;
                CurrentWSG.UnknownPT2QuestValue = OtherSave.UnknownPT2QuestValue;
                DoQuestTree();
            }
        }

        public bool MultipleIntroStateSaver(int Playthrough)
        {
            int TotalFound = 0;
            string[] PT;
            if (Playthrough == 1)
                PT = CurrentWSG.PT1Strings;
            else
                PT = CurrentWSG.PT2Strings;
            for (int Progress = 0; Progress < PT.Length; Progress++)
                if (PT[Progress] == "Z0_Missions.Missions.M_IntroStateSaver")
                    TotalFound = TotalFound + 1;
            if (TotalFound > 1)
                return true;
            else
                return false;
        }

        #endregion
        #region <<<<< ITEM PANEL >>>>>

        #region ---- Item List Functions ----

        private void AddItem(string Name, List<string> Parts, List<int> Values)
        {   // This doesn't create a new copy of the elements.
            CurrentWSG.ItemStrings.Add(Parts);
            CurrentWSG.ItemValues.Add(Values);
            ItemNames.Add(Name);
            CurrentWSG.NumberOfItems++;
        }
        private void CopyItem(int SourceIndex, int DestinationIndex)
        {   // Use new here to create a new copy of the elements.
            CurrentWSG.ItemStrings[DestinationIndex] = new List<string>(CurrentWSG.ItemStrings[SourceIndex]);
            CurrentWSG.ItemValues[DestinationIndex] = new List<int>(CurrentWSG.ItemValues[SourceIndex]);
            ItemNames[DestinationIndex] = ItemNames[DestinationIndex];
        }
        private void DuplicateItem(int Index)
        {   // Use new here to create a new copy of the elements.
            CurrentWSG.ItemStrings.Add(new List<string>(CurrentWSG.ItemStrings[Index]));
            CurrentWSG.ItemValues.Add(new List<int>(CurrentWSG.ItemValues[Index]));
            ItemNames.Add(ItemNames[Index]);
            CurrentWSG.NumberOfItems++;
        }
        private void InsertItem(int Index, string Name, List<string> Parts, List<int> Values)
        {
            CurrentWSG.ItemStrings.Insert(Index, Parts);
            CurrentWSG.ItemValues.Insert(Index, Values);
            ItemNames.Insert(Index, Name);
            CurrentWSG.NumberOfItems++;
        }
        private void RemoveItem(int Index)
        {
            CurrentWSG.ItemStrings.RemoveAt(Index);
            CurrentWSG.ItemValues.RemoveAt(Index);
            ItemNames.RemoveAt(Index);
            CurrentWSG.NumberOfItems--;
        }

        private void ImportFromTextItem(string text)
        {
            InOutPartsBox.Clear();
            InOutPartsBox.Text = text.Replace(" ", "");

            for (int Progress = 0; Progress < 9; Progress++)
            {   // Exception if any of these strings represent int values
                ThrowExceptionIfIntString(InOutPartsBox.Lines[Progress]);
                PartsItem.Items[Progress] = InOutPartsBox.Lines[Progress];
            }

            // Exception if any of these strings do not represent int values
            QuantityItem.Value = Convert.ToInt32(InOutPartsBox.Lines[9]);
            QualityItem.Value = Convert.ToInt32(InOutPartsBox.Lines[10]);
            Convert.ToInt32(InOutPartsBox.Lines[11]); // validate the input but dont use
            EquippedSlotItem.SelectedIndex = 0; // instead set equipped slot to 0
            LevelIndexItem.Value = Convert.ToInt32(InOutPartsBox.Lines[12]);

            NameItem = GetItemNameAdvanced(InOutPartsBox.Lines);
        }
        private void InsertFromTextItem(string text)
        {
            InOutPartsBox.Clear();
            InOutPartsBox.Text = text.Replace(" ", "");

            // Create new lists
            List<string> itemstrings = new List<string>();
            List<int> itemvalues = new List<int>();

            for (int Progress = 0; Progress < 9; Progress++)
            {
                ThrowExceptionIfIntString(InOutPartsBox.Lines[Progress]);
                itemstrings.Add(InOutPartsBox.Lines[Progress]);
            }

            for (int Progress = 0; Progress < 4; Progress++)
                itemvalues.Add(Convert.ToInt32(InOutPartsBox.Lines[Progress + 9]));
            itemvalues[2] = 0;  // set equipped slot to 0

            string itemname = GetItemNameAdvanced(itemstrings);

            AddItem(itemname, itemstrings, itemvalues);
            ItemTree.Nodes.Add(itemname);
        }
        private string ExportToTextItem()
        {
            InOutPartsBox.Clear();
            for (int Progress = 0; Progress < 9; Progress++)
            {
                if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                InOutPartsBox.AppendText((string)PartsItem.Items[Progress]);
            }
            InOutPartsBox.AppendText("\r\n" + QuantityItem.Value);
            InOutPartsBox.AppendText("\r\n" + QualityItem.Value);
            InOutPartsBox.AppendText("\r\n" + EquippedSlotItem.SelectedIndex);
            InOutPartsBox.AppendText("\r\n" + LevelIndexItem.Value);
            InOutPartsBox.AppendText("\r\n");

            return InOutPartsBox.Text;
        }

        #endregion

        private void DeleteItem_Click(object sender, EventArgs e)
        {
            if (ItemTree.SelectedNode == null)
                return;
            int Selected = ItemTree.SelectedNode.Index;

            ItemTree.SelectedNode = null;
            //ItemTree.DeselectNode(ItemTree.SelectedNode, new eTreeAction());
            ItemTree.Nodes.RemoveAt(Selected);
            RemoveItem(Selected);
            TrySelectedNode(ItemTree, Selected);
        } // Delete Item

        private void DeletePartItem_Click(object sender, EventArgs e)
        {
            PartsItem.Items[PartsItem.SelectedIndex] = "None";
        } // Delete Part

        private void DuplicateItem_Click(object sender, EventArgs e)
        {
            if (ItemTree.SelectedNode == null)
                return;
            int Selected = ItemTree.SelectedNode.Index;

            DuplicateItem(Selected);
            ItemTree.Nodes.Add((TreeNode)ItemTree.SelectedNode.Clone());
        } // Duplicate Item

        //private void EditLevelAllItems_Click(object sender, EventArgs e)
        //{
        //    string tempNewLevels = Interaction.InputBox("All of the items in your backpack will be adjusted to the following level:", "Edit All Levels", "", 10, 10);
        //    if (tempNewLevels != "" && tempNewLevels == "" + Convert.ToInt32(tempNewLevels))
        //    {
        //        foreach (List<int> item in CurrentWSG.ItemValues)
        //            item[3] = Convert.ToInt32(tempNewLevels) + 2;
        //        LevelIndexItem.Value = Convert.ToInt32(tempNewLevels) + 2;
        //    }
        //}

        private void EditQualityAllItems_Click(object sender, EventArgs e)
        {
            int quality;
            string qualityText = Interaction.InputBox("All of the items in your backpack will be adjusted to the following level:", "Edit All Qualitys", "", 10, 10);
            try
            {
                quality = Convert.ToInt32(qualityText);
            }
            catch (FormatException) { return; }

            foreach (List<int> item in CurrentWSG.ItemValues)
                item[3] = quality;

            QualityItem.Value = quality;
        }
        private void EditLevelAllItems_Click(object sender, EventArgs e)
        {
            int levelindex;
            string levelText = Interaction.InputBox("All of the items in your backpack will be adjusted to the following level:", "Edit All Levels", "", 10, 10);
            try
            {
                levelindex = Convert.ToInt32(levelText) + 2;
            }
            catch (FormatException) { return; }

            foreach (List<int> item in CurrentWSG.ItemValues)
                item[3] = levelindex;

            LevelIndexItem.Value = levelindex;
        }

        private void ExportToClipboardItem_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(ExportToTextItem());
        } // Export -> to Clipboard
        private void ExportToFileItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog ToFile = new SaveFileDialog();
            ToFile.DefaultExt = "*.txt";
            ToFile.Filter = "Item Files(*.txt)|*.txt";
            ToFile.FileName = WeaponPartsGroup.Text + ".txt";
            if (ToFile.ShowDialog() == DialogResult.OK)
            {
                System.IO.File.WriteAllText(ToFile.FileName, ExportToTextItem());
            }
        } // Export -> to File
        private void ExportToLockerItem_Click(object sender, EventArgs e)
        {
            List<string> itemparts = new List<string>();
            List<int> itemvalues = new List<int>()
                {
                    (int)QuantityItem.Value,
                    QualityItem.Value,
                    0,
                    LevelIndexItem.Value
                };

            InOutPartsBox.Clear();
            itemparts = new List<string>((IEnumerable<string>)PartsItem.Items);

            //for (int Progress = 0; Progress < 9; Progress++)
            //{
            //    itemparts.Add((string)PartsItem.Items[Progress]);
            //}

            string itemname = NameItem;
            //New Item

            List<string> iniListSectionNames = new List<string>();
            iniListSectionNames = XmlLocker.stListSectionNames();
            iniListSectionNames.TrimExcess();

            int Occurances = 0;

            if (iniListSectionNames.Contains(itemname))
            {
                // rename and try again until in can be added
                do
                {
                    Occurances++;
                } while (iniListSectionNames.Contains(itemname + " (Copy " + Occurances + ")"));
                //More than one found

                //Add new Item to the xml locker
                XmlLocker.AddItem(itemname + " (Copy " + Occurances + ")", "Weapon", itemparts, itemvalues);

                TreeNode temp = new TreeNode();
                temp.Text = itemname + " (Copy " + Occurances + ")";
                temp.Name = itemname + " (Copy " + Occurances + ")";
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text + " (Copy " + Occurances + ")");
            }
            else
            {
                //only one found
                XmlLocker.AddItem(itemname, "Item", itemparts, itemvalues);

                XmlLocker.Reload(); // Reload the locker next time

                TreeNode temp = new TreeNode();
                temp.Text = itemname;
                temp.Name = itemname;
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text);
            }
        }
        private void ExportToXmlItems_Click(object sender, EventArgs e)
        {
            SaveFileDialog tempExport = new SaveFileDialog();
            tempExport.DefaultExt = "*.xml";
            tempExport.Filter = "WillowTree Locker(*.xml)|*.xml";

            tempExport.FileName = CurrentWSG.CharacterName + "'s Items.xml";
            //string ExportText = "";
            if (tempExport.ShowDialog() == DialogResult.OK)
            {
                // Create empty xml file
                XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 2;
                writer.WriteStartDocument();
                writer.WriteStartElement("INI");
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();
                writer.Close();

                XmlFile LockerSave = new XmlFile(tempExport.FileName);
                List<string> itemparts = new List<string>();
                List<int> itemvalues = new List<int>();
         
                for (int Progress = 0; Progress < CurrentWSG.NumberOfItems; Progress++)
                {
                    itemparts.Clear();
                    itemvalues.Clear();
                    for (int PartProgress = 0; PartProgress < 9; PartProgress++)
                        itemparts.Add(CurrentWSG.ItemStrings[Progress][PartProgress]);

                    for (int PartProgress = 0; PartProgress < 4; PartProgress++)
                        itemvalues.Add(CurrentWSG.ItemValues[Progress][PartProgress]);

                    LockerSave.AddItem(ItemNames[Progress], "Item", itemparts, itemvalues);
                }
            }
        }

        private void ImportFromClipboardItem_Click(object sender, EventArgs e)
        {
            InOutPartsBox.Clear();
            InOutPartsBox.Text = Clipboard.GetText();
            InOutPartsBox.Text = InOutPartsBox.Text.Replace(" ", "");

            try
            {
                ImportFromTextItem(Clipboard.GetText());
            }
            catch
            {
                MessageBox.Show("Invalid clipboard data.  Reverting to saved values.");
                ItemTree_AfterNodeSelect(null, null);  // reloads the saved values from the node
            }
        }// Import -> from Clipboard
        private void ImportFromFileItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Item Files(*.txt)|*.txt";

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";

            if (FromFile.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ImportFromTextItem(System.IO.File.ReadAllText(FromFile.FileName));
                }
                catch
                {
                    MessageBox.Show("Invalid file data.  Reverting to saved values.");
                    ItemTree_AfterNodeSelect(null, null);  // reloads the saved values from the node
                }
            }
        } // Import -> from File

        private void InsertFromClipboardItem_Click(object sender, EventArgs e) // Insert -> from Clipboard
        {
            try
            {
                InsertFromTextItem(Clipboard.GetText());
            }
            catch (FormatException)
            {
                MessageBox.Show("Invalid clipboard data.  Item not inserted.");
                return;
            }
        }
        private void InsertFromFileItem_Click(object sender, EventArgs e) // Insert -> from File
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Item Files(*.txt)|*.txt";

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";

            if (FromFile.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    InsertFromTextItem(System.IO.File.ReadAllText(FromFile.FileName));
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid file data.  Item not inserted.");
                    return;
                }
             }
        }
        private void InsertFromFilesItems_Click(object sender, EventArgs e)
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Item Files(*.txt)|*.txt";
            FromFile.Multiselect = true;

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";

            if (FromFile.ShowDialog() == DialogResult.OK)
            {
                foreach (String file in FromFile.FileNames)
                {
                    try
                    {
                        InsertFromTextItem(System.IO.File.ReadAllText(file));
                    }
                    catch (FormatException)
                    {
                        MessageBox.Show("Invalid file data in " + file +".  Item not inserted.");
                        return;
                    }
                }
            }
        }
        private void InsertFromXmlItems_Click(object sender, EventArgs e)
        {
            OpenFileDialog tempImport = new OpenFileDialog();
            tempImport.DefaultExt = "*.xml";
            tempImport.Filter = "WillowTree Locker(*.xml)|*.xml";

            tempImport.FileName = CurrentWSG.CharacterName + "'s Items.xml";
            if (tempImport.ShowDialog() == DialogResult.OK)
            {
                XmlFile ImportWTL = new XmlFile(tempImport.FileName);

                for (int Progress = 0; Progress < ImportWTL.stListSectionNames("Item").Count; Progress++)
                {
                    List<string> itemstrings = new List<string>();
                    List<int> itemvalues = new List<int>();
                    string itemname;

                    List<string> sectionnames = ImportWTL.stListSectionNames("Item");

                    try 
                    {
                        itemname = sectionnames[Progress];
                        for (int ProgressStrings = 0; ProgressStrings < 9; ProgressStrings++)
                        {
                            string part = ImportWTL.XmlReadValue(itemname, "Part" + (ProgressStrings + 1));
                            ThrowExceptionIfIntString(part);
                            itemstrings.Add(part);
                        }
                                           
                        itemvalues.Add(Int32FromString(ImportWTL.XmlReadValue(itemname, "RemAmmo_Quantity"),0));
                        itemvalues.Add(Int32FromString(ImportWTL.XmlReadValue(itemname, "Quality"),0));
                        itemvalues.Add(0); // set equipped slot to 0
                        itemvalues.Add(Int32FromString(ImportWTL.XmlReadValue(itemname, "Level"),0));

                    }
                    catch
                    {
                        MessageBox.Show("Error reading XML file.  Some items were not read.");
                        break;
                    }

                    AddItem(itemname, itemstrings, itemvalues);
                }
                DoItemTree();
            }
        }

        private void ItemTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                PartsItem.Items.Clear();
                ItemPartsGroup.Text = ItemTree.SelectedNode.Text;

                //for (int ndcnt = 0; ndcnt < ItemPartsSelector.Nodes.Count; ndcnt++)
                //    ItemPartsSelector.Nodes[ndcnt].Style = elementStyle15;

                for (int build_list = 0; build_list < 9; build_list++)
                {
                    string curItempart = CurrentWSG.ItemStrings[ItemTree.SelectedNode.Index][build_list];
                    PartsItem.Items.Add(curItempart);


                    // highlight the used partfamilies in the partscategories tree
                    if (curItempart.Contains('.'))
                    {
                        string curItempartclass = curItempart.Substring(0, curItempart.IndexOf('.'));
                        for (int ndcnt = 0; ndcnt < PartCategoriesItem.Nodes.Count; ndcnt++)
                        {
                            //if (ItemPartsSelector.Nodes[ndcnt].Name == curItempartclass)
                            //{
                            //    ItemPartsSelector.Nodes[ndcnt].Style = elementStyle16;
                            //    break;
                            //}
                        }
                    }
                }

                QuantityItem.Value = CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][0];
                QualityItem.Value = CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][1];
                if (CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][2] == 0) EquippedSlotItem.SelectedItem = "No";
                else if (CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][2] == 1) EquippedSlotItem.SelectedItem = "Yes";
                LevelIndexItem.Value = CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][3];
                //string hex = String.Format("{x}", CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][0]);
                //hex01.Text = String.Format("0x{0:x8}", CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][0]);
                //hex02.Text = String.Format("0x{0:x8}", CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][1]);
                //hex03.Text = String.Format("0x{0:x8}", CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][2]);
                //hex04.Text = String.Format("0x{0:x8}", CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][3]);

                NameItem = ItemNames[ItemTree.SelectedNode.Index];
            }
            catch { }

        }

        private void NewItem_Click(object sender, EventArgs e)
        {
            try
            {
                string itemName = "New Item";
                List<int> itemValues = new List<int>(4) { 1, 0, 0, 0 };
                List<string> itemStrings = new List<string>(9)
                {
                    "Item Grade",
                    "Item Type",
                    "Body",
                    "Left Side",
                    "Right Side",
                    "Material",
                    "Manufacturer",
                    "Prefix",
                    "Title"
                };

                AddItem("New Item", itemStrings, itemValues);

                ItemTree.Nodes.Add(itemName);
                //DoItemTree();
            }
            catch { }
        }

        private void PartCategoriesItem_AfterSelect(object sender, TreeViewEventArgs e)
        {
            PartInfoItem.Clear();
            try
            {
                // Read ALL subsections of a given XML section
                // File: (DataPath + PartCategories.SelectedNode.Parent.Text + ".txt")
                XmlFile Category = new XmlFile(DataPath + PartCategoriesItem.SelectedNode.Parent.Text + ".txt");

                // XML Section: PartCategories.SelectedNode.Text
                List<string> xmlSection = Category.XmlReadSection(PartCategoriesItem.SelectedNode.Text);

                PartInfoItem.Lines = xmlSection.ToArray();

            }
            catch { }
        }
        private void PartCategoriesItem_NodeDoubleClick(object sender, MouseEventArgs e)
        {
            if (PartsItem.SelectedItem != null && PartCategoriesItem.SelectedNode.FirstNode == null)
            {
                PartsItem.Items[PartsItem.SelectedIndex] = PartCategoriesItem.SelectedNode.Parent.Text + "." + PartCategoriesItem.SelectedNode.Text;
            }
        }

        private void PartsItem_DoubleClick(object sender, EventArgs e)
        {
            string tempManualPart = Interaction.InputBox("Enter a new part", "Manual Edit", (string)PartsItem.SelectedItem, 10, 10);
            if (tempManualPart != "")
                PartsItem.Items[PartsItem.SelectedIndex] = tempManualPart;

        }
        private void PartsItem_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (PartsItem.SelectedIndex == -1)
                return;

            string part = (string)PartsItem.Items[PartsItem.SelectedIndex];
            try
            {
                PartCategoriesItem.SelectedNode = PartCategoriesItem.Nodes[part.Before('.')].Nodes[part.After('.')];
            }
            catch { }
        }

        private void SaveChangesItem_Click(object sender, EventArgs e)
        {
            try
            {
                int Selected = ItemTree.SelectedNode.Index;

                for (int Progress = 0; Progress < 9; Progress++)
                    CurrentWSG.ItemStrings[ItemTree.SelectedNode.Index][Progress] = (string)PartsItem.Items[Progress];
                CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][0] = (int)QuantityItem.Value;
                CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][1] = (int)QualityItem.Value;
                CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][2] = EquippedSlotItem.SelectedIndex;
                CurrentWSG.ItemValues[ItemTree.SelectedNode.Index][3] = (int)LevelIndexItem.Value;
                //DoItemTree();
                //DoItemTree();
                //ItemTree.SelectedNode = ItemTree.Nodes[Selected];
                ItemNames[ItemTree.SelectedNode.Index] = GetItemNameAdvanced(CurrentWSG.ItemStrings[ItemTree.SelectedNode.Index]);
                ItemTree.SelectedNode.Text = ItemNames[ItemTree.SelectedNode.Index];
            }
            catch { }
        } // Save Changes

        #endregion
        #region <<<<< ECHO PANEL >>>>

        private void DeleteEcho_Click(object sender, EventArgs e)
        {
            try
            {
                int Selected = EchoTree.SelectedNode.Index; ;
                if (EchoTree.SelectedNode.Name == "PT1")
                {
                    Selected = EchoTree.SelectedNode.Index;
                    CurrentWSG.NumberOfEchos = CurrentWSG.NumberOfEchos - 1;
                    for (int Position = Selected; Position < CurrentWSG.NumberOfEchos; Position++)
                    {
                        CurrentWSG.EchoStrings[Position] = CurrentWSG.EchoStrings[Position + 1];
                        for (int Progress = 0; Progress < 2; Progress++)
                            CurrentWSG.EchoValues[Position, Progress] = CurrentWSG.EchoValues[Position + 1, Progress];

                    }
                    ResizeArraySmaller(ref CurrentWSG.EchoStrings, CurrentWSG.NumberOfEchos);
                    ResizeArraySmaller(ref CurrentWSG.EchoValues, CurrentWSG.NumberOfEchos, 2);
                    DoEchoTree();
                    EchoTree.SelectedNode = EchoTree.Nodes[0].Nodes[Selected];
                }
                else if (EchoTree.SelectedNode.Name == "PT2")
                {
                    Selected = EchoTree.SelectedNode.Index;
                    CurrentWSG.NumberOfEchosPT2 = CurrentWSG.NumberOfEchosPT2 - 1;
                    for (int Position = Selected; Position < CurrentWSG.NumberOfEchosPT2; Position++)
                    {
                        CurrentWSG.EchoStringsPT2[Position] = CurrentWSG.EchoStringsPT2[Position + 1];
                        for (int Progress = 0; Progress < 2; Progress++)
                            CurrentWSG.EchoValuesPT2[Position, Progress] = CurrentWSG.EchoValuesPT2[Position + 1, Progress];

                    }
                    ResizeArraySmaller(ref CurrentWSG.EchoStringsPT2, CurrentWSG.NumberOfEchosPT2);
                    ResizeArraySmaller(ref CurrentWSG.EchoValuesPT2, CurrentWSG.NumberOfEchosPT2, 2);

                    DoEchoTree();

                    try
                    {
                        EchoTree.SelectedNode = EchoTree.Nodes[1].Nodes[Selected];
                    }
                    catch { }

                }
            }
            catch { }
        }

        private void EchoList_Click(object sender, EventArgs e)
        {
            if (EchoTree.SelectedNode == null)
                return;
            XmlFile Echoes = new XmlFile(DataPath + "Echos.ini");
            if (EchoTree.SelectedNode.Name == "PT1" || EchoTree.SelectedNode.Text == "Playthrough 1 Echo Logs")
            {
                if (EchoList.SelectedIndex == -1)
                    return;
                if (CheckIfNull(CurrentWSG.EchoStrings) == true)
                {
                    CurrentWSG.EchoStrings = new string[1];
                    CurrentWSG.EchoStrings[0] = Echoes.stListSectionNames()[EchoList.SelectedIndex];
                    CurrentWSG.EchoValues = new int[1, 2];
                    CurrentWSG.NumberOfEchos = 1;
                }
                else
                {
                    CurrentWSG.NumberOfEchos = CurrentWSG.NumberOfEchos + 1;
                    ResizeArrayLarger(ref CurrentWSG.EchoStrings, CurrentWSG.NumberOfEchos);
                    ResizeArrayLarger(ref CurrentWSG.EchoValues, CurrentWSG.NumberOfEchos, 2);
                    CurrentWSG.EchoStrings[CurrentWSG.NumberOfEchos - 1] = Echoes.stListSectionNames()[EchoList.SelectedIndex];

                }
                DoEchoTree();
                EchoTree.Nodes[0].Expand();
                EchoTree.SelectedNode = EchoTree.Nodes[0];
            }
            else if (EchoTree.SelectedNode.Name == "PT2" || EchoTree.SelectedNode.Text == "Playthrough 2 Echo Logs")
            {

                if (CheckIfNull(CurrentWSG.EchoStringsPT2) == true)
                {
                    if (CurrentWSG.TotalPT2Quests > 1)
                    {
                        CurrentWSG.EchoStringsPT2 = new string[1];
                        CurrentWSG.EchoStringsPT2[0] = Echoes.stListSectionNames()[EchoList.SelectedIndex];
                        CurrentWSG.EchoValuesPT2 = new int[1, 2];
                        CurrentWSG.NumberOfEchosPT2 = 1;
                    }
                    else
                        MessageBox.Show("You must have more than just the default quest.");
                }
                else
                {
                    CurrentWSG.NumberOfEchosPT2 = CurrentWSG.NumberOfEchosPT2 + 1;
                    ResizeArrayLarger(ref CurrentWSG.EchoStringsPT2, CurrentWSG.NumberOfEchosPT2);
                    ResizeArrayLarger(ref CurrentWSG.EchoValuesPT2, CurrentWSG.NumberOfEchosPT2, 2);
                    CurrentWSG.EchoStringsPT2[CurrentWSG.NumberOfEchosPT2 - 1] = Echoes.stListSectionNames()[EchoList.SelectedIndex];

                }
                DoEchoTree();
                EchoTree.Nodes[1].Expand();
                EchoTree.SelectedNode = EchoTree.Nodes[1];
            }
            //try
            //{ }
            //catch { MessageBox.Show("Could not add new echo log"); }
        }

        private void ExportEchoes_Click(object sender, EventArgs e)
        {
            try
            {
                if (EchoTree.SelectedNode.Name == "PT2" || EchoTree.SelectedNode.Text == "Playthrough 2 Echo Logs")
                {
                    SaveFileDialog tempExport = new SaveFileDialog();
                    //string ExportText = "";
                    tempExport.DefaultExt = "*.echologs";
                    tempExport.Filter = "Echo Logs(*.echologs)|*.echologs";

                    tempExport.FileName = CurrentWSG.CharacterName + "'s PT2 Echo Logs.echologs";

                    if (tempExport.ShowDialog() == DialogResult.OK)
                    {
                        // Create empty xml file
                        XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                        writer.Formatting = Formatting.Indented;
                        writer.Indentation = 2;
                        writer.WriteStartDocument();
                        writer.WriteStartElement("INI");
                        writer.WriteEndElement();
                        writer.WriteEndDocument();
                        writer.Flush();
                        writer.Close();

                        XmlFile Echos = new XmlFile(tempExport.FileName);
                        List<string> subsectionnames = new List<string>();
                        List<string> subsectionvalues = new List<string>();

                        for (int Progress = 0; Progress < CurrentWSG.NumberOfEchosPT2; Progress++)
                        {
                            subsectionnames.Clear();
                            subsectionvalues.Clear();
                            subsectionnames.Add("DLCValue1");
                            subsectionnames.Add("DLCValue2");
                            subsectionvalues.Add(CurrentWSG.EchoValuesPT2[Progress, 0].ToString());
                            subsectionvalues.Add(CurrentWSG.EchoValuesPT2[Progress, 1].ToString());

                            //ExportText = ExportText + "[" + CurrentWSG.EchoStringsPT2[Progress] + "]" + "\r\nDLCValue1=" + CurrentWSG.EchoValuesPT2[Progress, 0] + "\r\nDLCValue2=" + CurrentWSG.EchoValuesPT2[Progress, 1] + "\r\n";
                            Echos.AddSection(CurrentWSG.EchoStringsPT2[Progress], subsectionnames, subsectionvalues);
                        }
                        //File.WriteAllText(tempExport.FileName + "s", ExportText);
                    }
                }
                else if (EchoTree.SelectedNode.Name == "PT1" || EchoTree.SelectedNode.Text == "Playthrough 1 Echo Logs")
                {
                    SaveFileDialog tempExport = new SaveFileDialog();
                    //string ExportText = "";
                    tempExport.DefaultExt = "*.echologs";
                    tempExport.Filter = "Echo Logs(*.echologs)|*.echologs";

                    tempExport.FileName = CurrentWSG.CharacterName + "'s PT1 Echo Logs.echologs";

                    if (tempExport.ShowDialog() == DialogResult.OK)
                    {
                        // Create empty xml file
                        XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                        writer.Formatting = Formatting.Indented;
                        writer.Indentation = 2;
                        writer.WriteStartDocument();
                        writer.WriteStartElement("INI");
                        writer.WriteEndElement();
                        writer.WriteEndDocument();
                        writer.Flush();
                        writer.Close();

                        XmlFile Echos = new XmlFile(tempExport.FileName);
                        List<string> subsectionnames = new List<string>();
                        List<string> subsectionvalues = new List<string>();

                        for (int Progress = 0; Progress < CurrentWSG.NumberOfEchos; Progress++)
                        {
                            subsectionnames.Clear();
                            subsectionvalues.Clear();
                            subsectionnames.Add("DLCValue1");
                            subsectionnames.Add("DLCValue2");
                            subsectionvalues.Add(CurrentWSG.EchoValues[Progress, 0].ToString());
                            subsectionvalues.Add(CurrentWSG.EchoValues[Progress, 1].ToString());

                            //ExportText = ExportText + "[" + CurrentWSG.EchoStrings[Progress] + "]" + "\r\nDLCValue1=" + CurrentWSG.EchoValues[Progress, 0] + "\r\nDLCValue2=" + CurrentWSG.EchoValues[Progress, 1] + "\r\n";
                            Echos.AddSection(CurrentWSG.EchoStrings[Progress], subsectionnames, subsectionvalues);

                        }
                        //File.WriteAllText(tempExport.FileName + "s", ExportText);
                    }

                }
            }
            catch { MessageBox.Show("Select a playthrough to export first."); }
        }

        private void ImportEchoes_Click(object sender, EventArgs e)
        {
            //try
            //{
            if (EchoTree.SelectedNode == null)
            {
                MessageBox.Show("Select a playthrough to import first.");
                return;
            }
            OpenFileDialog tempImport = new OpenFileDialog();
            if (EchoTree.SelectedNode.Name == "PT2" || EchoTree.SelectedNode.Text == "Playthrough 2 Echo Logs")
            {

                tempImport.DefaultExt = "*.echologs";
                tempImport.Filter = "Echo Logs(*.echologs)|*.echologs";

                tempImport.FileName = CurrentWSG.CharacterName + "'s PT2 Echo Logs.echologs";
                if (tempImport.ShowDialog() == DialogResult.OK)
                {
                    if (EchoTree.SelectedNode.Name == "PT2" || EchoTree.SelectedNode.Text == "Playthrough 2 Echo Logs")
                    {
                        //Ini.IniFile ImportLogs = new Ini.IniFile(tempImport.FileName);
                        XmlFile ImportLogs = new XmlFile(tempImport.FileName);
                        string[] TempEchoStrings = new string[ImportLogs.stListSectionNames().Count];
                        int[,] TempEchoValues = new int[ImportLogs.stListSectionNames().Count, 10];
                        for (int Progress = 0; Progress < ImportLogs.stListSectionNames().Count; Progress++)
                        {
                            TempEchoStrings[Progress] = ImportLogs.stListSectionNames()[Progress];
                            TempEchoValues[Progress, 0] = Convert.ToInt32(ImportLogs.XmlReadValue(ImportLogs.stListSectionNames()[Progress], "DLCValue1"));
                            TempEchoValues[Progress, 1] = Convert.ToInt32(ImportLogs.XmlReadValue(ImportLogs.stListSectionNames()[Progress], "DLCValue2"));


                        }
                        CurrentWSG.EchoStringsPT2 = TempEchoStrings;
                        CurrentWSG.EchoValuesPT2 = TempEchoValues;
                        CurrentWSG.NumberOfEchosPT2 = ImportLogs.stListSectionNames().Count;
                        DoEchoTree();
                    }
                }
            }
            else if (EchoTree.SelectedNode.Name == "PT1" || EchoTree.SelectedNode.Text == "Playthrough 1 Echo Logs")
            {
                tempImport.DefaultExt = "*.echologs";
                tempImport.Filter = "Echo Logs(*.echologs)|*.echologs";

                tempImport.FileName = CurrentWSG.CharacterName + "'s PT1 Echo Logs.echologs";



                if (tempImport.ShowDialog() == DialogResult.OK)
                {
                    //Ini.IniFile ImportLogs = new Ini.IniFile(tempImport.FileName);
                    XmlFile ImportLogs = new XmlFile(tempImport.FileName);
                    string[] TempEchoStrings = new string[ImportLogs.stListSectionNames().Count];
                    int[,] TempEchoValues = new int[ImportLogs.stListSectionNames().Count, 10];
                    for (int Progress = 0; Progress < ImportLogs.stListSectionNames().Count; Progress++)
                    {
                        TempEchoStrings[Progress] = ImportLogs.stListSectionNames()[Progress];
                        TempEchoValues[Progress, 0] = Convert.ToInt32(ImportLogs.XmlReadValue(ImportLogs.stListSectionNames()[Progress], "DLCValue1"));
                        TempEchoValues[Progress, 1] = Convert.ToInt32(ImportLogs.XmlReadValue(ImportLogs.stListSectionNames()[Progress], "DLCValue2"));


                    }
                    CurrentWSG.EchoStrings = TempEchoStrings;
                    CurrentWSG.EchoValues = TempEchoValues;
                    CurrentWSG.NumberOfEchos = ImportLogs.stListSectionNames().Count;
                    DoEchoTree();
                }

            }


            try
            {
            }
            catch { MessageBox.Show("Select a playthrough to import first."); }


        }

        private void EchoDLCValue1_ValueChanged(object sender, EventArgs e)
        {
            if (EchoTree.SelectedNode.Name == "PT2")
                CurrentWSG.EchoValuesPT2[EchoTree.SelectedNode.Index, 0] = (int)EchoDLCValue1.Value;
            else if (EchoTree.SelectedNode.Name == "PT1")
                CurrentWSG.EchoValues[EchoTree.SelectedNode.Index, 0] = (int)EchoDLCValue1.Value;
        }

        private void EchoDLCValue2_ValueChanged(object sender, EventArgs e)
        {
            if (EchoTree.SelectedNode.Name == "PT2")
                CurrentWSG.EchoValuesPT2[EchoTree.SelectedNode.Index, 1] = (int)EchoDLCValue2.Value;
            else if (EchoTree.SelectedNode.Name == "PT1")
                CurrentWSG.EchoValues[EchoTree.SelectedNode.Index, 1] = (int)EchoDLCValue2.Value;

        }

        private void EchoTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                if (EchoTree.SelectedNode.Name == "PT2")
                {
                    EchoDLCValue1.Value = CurrentWSG.EchoValuesPT2[EchoTree.SelectedNode.Index, 0];
                    EchoDLCValue2.Value = CurrentWSG.EchoValuesPT2[EchoTree.SelectedNode.Index, 1];
                }
                else if (EchoTree.SelectedNode.Name == "PT1")
                {
                    EchoDLCValue1.Value = CurrentWSG.EchoValues[EchoTree.SelectedNode.Index, 0];
                    EchoDLCValue2.Value = CurrentWSG.EchoValues[EchoTree.SelectedNode.Index, 1];
                }
            }
            catch { }
        }

        #endregion
        #region <<<<< SKILLS PANEL >>>>>

        private void SkillLevel_ValueChanged(object sender, EventArgs e)
        {
            try
            { CurrentWSG.LevelOfSkills[SkillTree.SelectedNode.Index] = (int)SkillLevel.Value; }
            catch { }
        }

        private void SkillExp_ValueChanged(object sender, EventArgs e)
        {
            try
            { CurrentWSG.ExpOfSkills[SkillTree.SelectedNode.Index] = (int)SkillExp.Value; }
            catch { }
        }

        private void SkillActive_SelectionChangeCommitted(object sender, EventArgs e)
        {
            try
            {
                if (SkillActive.SelectedIndex == 1)
                    CurrentWSG.InUse[SkillTree.SelectedNode.Index] = 1;
                else
                    CurrentWSG.InUse[SkillTree.SelectedNode.Index] = -1;
            }
            catch { }
        }

        private void DeleteSkill_Click(object sender, EventArgs e)
        {
            try
            {
                int Selected = SkillTree.SelectedNode.Index;
                CurrentWSG.NumberOfSkills = CurrentWSG.NumberOfSkills - 1;
                for (int Position = Selected; Position < CurrentWSG.NumberOfSkills; Position++)
                {
                    CurrentWSG.SkillNames[Position] = CurrentWSG.SkillNames[Position + 1];
                    CurrentWSG.InUse[Position] = CurrentWSG.InUse[Position + 1];
                    CurrentWSG.ExpOfSkills[Position] = CurrentWSG.ExpOfSkills[Position + 1];
                    CurrentWSG.LevelOfSkills[Position] = CurrentWSG.LevelOfSkills[Position + 1];

                }
                ResizeArraySmaller(ref CurrentWSG.SkillNames, CurrentWSG.NumberOfSkills);
                ResizeArraySmaller(ref CurrentWSG.InUse, CurrentWSG.NumberOfSkills);
                ResizeArraySmaller(ref CurrentWSG.ExpOfSkills, CurrentWSG.NumberOfSkills);
                ResizeArraySmaller(ref CurrentWSG.LevelOfSkills, CurrentWSG.NumberOfSkills);
                DoSkillTree();

                SkillTree.SelectedNode = SkillTree.Nodes[Selected];
            }
            catch { }
        }

        private void ExportToFileSkills_Click(object sender, EventArgs e)
        {
            SaveFileDialog tempExport = new SaveFileDialog();
            //string ExportText = "";
            tempExport.DefaultExt = "*.skills";
            tempExport.Filter = "Skills Data(*.skills)|*.skills";

            tempExport.FileName = CurrentWSG.CharacterName + "'s Skills.skills";

            if (tempExport.ShowDialog() == DialogResult.OK)
            {
                // Create empty xml file
                XmlTextWriter writer = new XmlTextWriter(tempExport.FileName, new System.Text.ASCIIEncoding());
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 2;
                writer.WriteStartDocument();
                writer.WriteStartElement("INI");
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();
                writer.Close();

                XmlFile Skills = new XmlFile(tempExport.FileName);
                List<string> subsectionnames = new List<string>();
                List<string> subsectionvalues = new List<string>();

                for (int Progress = 0; Progress < CurrentWSG.NumberOfSkills; Progress++)
                {
                    subsectionnames.Clear();
                    subsectionvalues.Clear();

                    subsectionnames.Add("Level");
                    subsectionnames.Add("Experience");
                    subsectionnames.Add("InUse");
                    subsectionvalues.Add(CurrentWSG.LevelOfSkills[Progress].ToString());
                    subsectionvalues.Add(CurrentWSG.ExpOfSkills[Progress].ToString());
                    subsectionvalues.Add(CurrentWSG.InUse[Progress].ToString());

                    //ExportText = ExportText + "[" + CurrentWSG.SkillNames[Progress] + "]\r\nLevel=" + CurrentWSG.LevelOfSkills[Progress] + "\r\nExperience=" + CurrentWSG.ExpOfSkills[Progress] + "\r\nInUse=" + CurrentWSG.InUse[Progress] + "\r\n";
                    Skills.AddSection(CurrentWSG.SkillNames[Progress], subsectionnames, subsectionvalues);
                }
                //File.WriteAllText(tempExport.FileName + "s", ExportText);
            }

        }

        private void ImportFromFileSkills_Click(object sender, EventArgs e)
        {
            OpenFileDialog tempImport = new OpenFileDialog();
            tempImport.DefaultExt = "*.skills";
            tempImport.Filter = "Skills Data(*.skills)|*.skills";

            tempImport.FileName = CurrentWSG.CharacterName + "'s Skills.skills";
            if (tempImport.ShowDialog() == DialogResult.OK)
            {

                //Ini.IniFile ImportSkills = new Ini.IniFile(tempImport.FileName);
                XmlFile ImportSkills = new XmlFile(tempImport.FileName);
                string[] TempSkillNames = new string[ImportSkills.stListSectionNames().Count];
                int[] TempSkillLevels = new int[ImportSkills.stListSectionNames().Count];
                int[] TempSkillExp = new int[ImportSkills.stListSectionNames().Count];
                int[] TempSkillInUse = new int[ImportSkills.stListSectionNames().Count];
                for (int Progress = 0; Progress < ImportSkills.stListSectionNames().Count; Progress++)
                {
                    TempSkillNames[Progress] = ImportSkills.stListSectionNames()[Progress];
                    TempSkillLevels[Progress] = Convert.ToInt32(ImportSkills.XmlReadValue(ImportSkills.stListSectionNames()[Progress], "Level"));
                    TempSkillExp[Progress] = Convert.ToInt32(ImportSkills.XmlReadValue(ImportSkills.stListSectionNames()[Progress], "Experience"));
                    TempSkillInUse[Progress] = Convert.ToInt32(ImportSkills.XmlReadValue(ImportSkills.stListSectionNames()[Progress], "InUse"));
                }
                CurrentWSG.SkillNames = TempSkillNames;
                CurrentWSG.LevelOfSkills = TempSkillLevels;
                CurrentWSG.ExpOfSkills = TempSkillExp;
                CurrentWSG.InUse = TempSkillInUse;
                CurrentWSG.NumberOfSkills = ImportSkills.stListSectionNames().Count;
                DoSkillTree();
            }
        }

        private void SkillList_Click(object sender, EventArgs e)
        {
            newToolStripMenuItem4.HideDropDown();
            try
            {
                XmlFile SkillINI = new XmlFile(DataPath + "gd_skills_common.txt");
                if ((string)Class.SelectedItem == "Soldier")
                    SkillINI = new XmlFile(DataPath + "gd_skills2_Roland.txt");

                else if ((string)Class.SelectedItem == "Siren")
                    SkillINI = new XmlFile(DataPath + "gd_Skills2_Lilith.txt");

                else if ((string)Class.SelectedItem == "Hunter")
                    SkillINI = new XmlFile(DataPath + "gd_skills2_Mordecai.txt");

                else if ((string)Class.SelectedItem == "Berserker")
                    SkillINI = new XmlFile(DataPath + "gd_Skills2_Brick.txt");

                CurrentWSG.NumberOfSkills = CurrentWSG.NumberOfSkills + 1;
                ResizeArrayLarger(ref CurrentWSG.SkillNames, CurrentWSG.NumberOfSkills);
                ResizeArrayLarger(ref CurrentWSG.LevelOfSkills, CurrentWSG.NumberOfSkills);
                ResizeArrayLarger(ref CurrentWSG.ExpOfSkills, CurrentWSG.NumberOfSkills);
                ResizeArrayLarger(ref CurrentWSG.InUse, CurrentWSG.NumberOfSkills);
                CurrentWSG.InUse[CurrentWSG.NumberOfSkills - 1] = -1;
                CurrentWSG.SkillNames[CurrentWSG.NumberOfSkills - 1] = SkillINI.stListSectionNames()[SkillList.SelectedIndex];
                DoSkillTree();
            }
            catch { MessageBox.Show("Could not add new Skill."); }
        }

        private void SkillTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                SkillName.Text = CurrentWSG.SkillNames[SkillTree.SelectedNode.Index];
                SkillLevel.Value = CurrentWSG.LevelOfSkills[SkillTree.SelectedNode.Index];
                SkillExp.Value = CurrentWSG.ExpOfSkills[SkillTree.SelectedNode.Index];
                if (CurrentWSG.InUse[SkillTree.SelectedNode.Index] == -1) SkillActive.SelectedItem = "No";
                else SkillActive.SelectedItem = "Yes";
            }
            catch { }
        }

        #endregion
        #region <<<<< AMMO PANEL >>>>>

        public string GetAmmoName(string d_resources)
        {
            if (d_resources == "d_resources.AmmoResources.Ammo_Sniper_Rifle")
                return "Sniper Rifle";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Repeater_Pistol")
                return "Repeater Pistol";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Grenade_Protean")
                return "Protean Grenades";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Patrol_SMG")
                return "Patrol SMG";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Combat_Shotgun")
                return "Combat Shotgun";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Combat_Rifle")
                return "Combat Rifle";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Revolver_Pistol")
                return "Revolver Pistol";
            else if (d_resources == "d_resources.AmmoResources.Ammo_Rocket_Launcher")
                return "Rocket Launcher";
            else
                return d_resources;
        }

        private void AmmoTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                AmmoPoolRemaining.Value = (decimal)CurrentWSG.RemainingPools[AmmoTree.SelectedNode.Index];
                AmmoSDULevel.Value = CurrentWSG.PoolLevels[AmmoTree.SelectedNode.Index];
            }
            catch { }
        }

        private void AmmoPoolRemaining_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                CurrentWSG.RemainingPools[AmmoTree.SelectedNode.Index] = (float)AmmoPoolRemaining.Value;
            }
            catch { }
        }

        private void AmmoSDULevel_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                CurrentWSG.PoolLevels[AmmoTree.SelectedNode.Index] = (int)AmmoSDULevel.Value;
            }

            catch { }
        }

        private void DeleteAmmo_Click(object sender, EventArgs e)
        {
            if (AmmoTree.SelectedNode != null)
            {
                CurrentWSG.NumberOfPools = CurrentWSG.NumberOfPools - 1;
                ResizeArraySmaller(ref CurrentWSG.AmmoPools, CurrentWSG.NumberOfPools);
                ResizeArraySmaller(ref CurrentWSG.ResourcePools, CurrentWSG.NumberOfPools);
                ResizeArraySmaller(ref CurrentWSG.RemainingPools, CurrentWSG.NumberOfPools);
                ResizeArraySmaller(ref CurrentWSG.PoolLevels, CurrentWSG.NumberOfPools);
                DoAmmoTree();
            }
        }

        private void NewAmmo_Click(object sender, EventArgs e)
        {
            try
            {
                string New_d_resources = Interaction.InputBox("Enter the 'd_resources' for the new Ammo Pool", "New Ammo Pool", "", 10, 10);
                string New_d_resourcepools = Interaction.InputBox("Enter the 'd_resourcepools' for the new Ammo Pool", "New Ammo Pool", "", 10, 10);
                if (New_d_resourcepools != "" && New_d_resources != "")
                {
                    CurrentWSG.NumberOfPools = CurrentWSG.NumberOfPools + 1;
                    ResizeArrayLarger(ref CurrentWSG.AmmoPools, CurrentWSG.NumberOfPools);
                    ResizeArrayLarger(ref CurrentWSG.ResourcePools, CurrentWSG.NumberOfPools);
                    ResizeArrayLarger(ref CurrentWSG.RemainingPools, CurrentWSG.NumberOfPools);
                    ResizeArrayLarger(ref CurrentWSG.PoolLevels, CurrentWSG.NumberOfPools);
                    CurrentWSG.AmmoPools[CurrentWSG.NumberOfPools - 1] = New_d_resourcepools;
                    CurrentWSG.ResourcePools[CurrentWSG.NumberOfPools - 1] = New_d_resources;
                    DoAmmoTree();
                }
            }
            catch { MessageBox.Show("Couldn't add new ammo pool."); }
        }

        #endregion
        #region <<<<< LOCKER PANEL >>>>>

        private XmlFile XmlLocker = new XmlFile(DataPath + "default.xml");

        private void btnlockerSearch_Click(object sender, EventArgs e)
        {
            List<string> searchresults;
            searchresults = XmlLocker.XmlSearchSection(lockerSearch.Text);

            int start = 0;

            //            for (int ndcnt = start; ndcnt < LockerTree.Nodes.Count; ndcnt++)
            // Set all nodes to standard style
            //                LockerTree.Nodes[ndcnt].Style = elementStyle5;

            int srcnt = 0;
            int srfcnt = 0;
            foreach (string searchresult in searchresults)
            {
                srcnt++;
                for (int ndcnt = 0; ndcnt < LockerTree.Nodes.Count; ndcnt++)
                {

                    if (LockerTree.Nodes[ndcnt].Name == searchresult)
                    {
                        //                        LockerTree.Nodes[ndcnt].Style = elementStyle6;
                        start = ndcnt + 1;
                        srfcnt++;
                        break;
                    }
                }
            }
        }

        private void DeleteLocker_Click(object sender, EventArgs e)
        {
            if (LockerTree.SelectedNode == null)
            {
                MessageBox.Show("Select an item to delete first.");
                return;
            }
            int SelectedIndex = LockerTree.SelectedNode.Index;

            XmlLocker.RemoveItem(LockerTree.SelectedNode.Name);

            LockerTree.Nodes[SelectedIndex].Remove();

            //DoLockerTree(OpenedLocker);
            try
            {
                LockerTree.SelectedNode = LockerTree.Nodes[SelectedIndex];
            }
            catch { }

            /*            try
                        {
                            int Selected = LockerTree.SelectedIndex;
                            string search = "[" + LockerTree.SelectedNode.Text + "]";

                            string[] tempINI2 = System.IO.File.ReadAllLines(OpenedLocker);

                            int DiscoveredLine = -1;
                            for (int Progress = 0; Progress < tempINI2.Length; Progress++)
                            {
                                //string tewst = tempINI2[Progress].Substring(0, tempINI2[Progress].Length - 1);
                                if (tempINI2[Progress] == search)
                                    DiscoveredLine = Progress;


                            }
                            for (int Progress = 0; Progress < 18; Progress++)
                                tempINI2[DiscoveredLine + Progress] = "";
                            System.IO.File.WriteAllLines(OpenedLocker, tempINI2);
                            DoLockerTree(OpenedLocker);
                            try
                            {
                                LockerTree.SelectedIndex = Selected;
                            }
                            catch { }
                        }
                        catch { }*/
        }

        private string ExportToTextLocker()
        {
            int Loops = 0;
            InOutPartsBox.Clear();
            if (ItemTypeLocker.SelectedIndex == 0) Loops = 14;
            else if (ItemTypeLocker.SelectedIndex == 1) Loops = 9;
            for (int Progress = 0; Progress < Loops; Progress++)
            {
                if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                InOutPartsBox.AppendText((string)PartsLocker.Items[Progress]);
            }
            if (OverrideExportSettings.Checked == true)
            {
                InOutPartsBox.AppendText("\r\n" + RemAmmoOverride.Value);
                InOutPartsBox.AppendText("\r\n" + LevelIndexOverride.Value);
                InOutPartsBox.AppendText("\r\n0");
                InOutPartsBox.AppendText("\r\n" + QualityOverride.Value);
            }
            else
            {
                InOutPartsBox.AppendText("\r\n" + RemAmmoLocker.Value);
                InOutPartsBox.AppendText("\r\n" + QualityLocker.Value);
                InOutPartsBox.AppendText("\r\n0");
                InOutPartsBox.AppendText("\r\n" + LevelIndexLocker.Value);
            }
            InOutPartsBox.AppendText("\r\n");
            return InOutPartsBox.Text;
        }

        private void ExportToFileLocker_Click(object sender, EventArgs e)
        {
            SaveFileDialog ToFile = new SaveFileDialog();
            ToFile.DefaultExt = "*.txt";
            ToFile.Filter = "Item Files(*.txt)|*.txt";
            ToFile.FileName = NameLocker.Text + ".txt";
            if (ToFile.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    System.IO.File.WriteAllText(ToFile.FileName, ExportToTextLocker());
                }
                catch { MessageBox.Show("Export to file failed."); }
            }
        }

        private void ExportToClipboardLocker_Click(object sender, EventArgs e)
        {
            try
            {
                Clipboard.SetText(ExportToTextLocker());
            }
            catch { MessageBox.Show("Export to clipboard failed."); }
        }

        private void ExportToBackpackLocker_Click(object sender, EventArgs e)
        {
            List<string> selectednodes = new List<string>();

            TreeNode selnode = LockerTree.SelectedNode;
            if (selnode == null)
                return;

            //            foreach (Node selnode in LockerTree.SelectedNodes)
            {
                //XmlFile Locker = new XmlFile(OpenedLocker);

                if (selnode.FirstNode != null)
                {
                    foreach (TreeNode childnode in selnode.Nodes)
                    {
                        selectednodes.Add(childnode.Name);
                    }
                }
                else
                {
                    selectednodes.Add(selnode.Name);
                }
            }

            //We got all selected nodes in a list
            foreach (string LockerSelected in selectednodes)
            {
                PartsLocker.Items.Clear();
                NameLocker.Text = LockerSelected;

                RatingLocker.Text = XmlLocker.XmlReadValue(LockerSelected, "Rating");
                DescriptionLocker.Text = XmlLocker.XmlReadValue(LockerSelected, "Description");
                DescriptionLocker.Text = DescriptionLocker.Text.Replace("$LINE$", "\r\n");
                ItemTypeLocker.SelectedItem = XmlLocker.XmlReadValue(LockerSelected, "Type");

                for (int Progress = 0; Progress < 14; Progress++)
                    PartsLocker.Items.Add(XmlLocker.XmlReadValue(LockerSelected, "Part" + (Progress + 1)));

                if (ItemTypeLocker.SelectedIndex == 0)
                {
                    InOutPartsBox.Clear();

                    for (int Progress = 0; Progress < 14; Progress++)
                    {
                        if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                        InOutPartsBox.AppendText((string)PartsLocker.Items[Progress]);
                    }

                    if (OverrideExportSettings.Checked == true)
                    {
                        InOutPartsBox.AppendText("\r\n" + RemAmmoOverride.Value);
                        InOutPartsBox.AppendText("\r\n" + LevelIndexOverride.Value);
                        InOutPartsBox.AppendText("\r\n0");
                        InOutPartsBox.AppendText("\r\n" + QualityOverride.Value);
                    }
                    else
                    {
                        InOutPartsBox.AppendText("\r\n" + RemAmmoLocker.Value);
                        InOutPartsBox.AppendText("\r\n" + QualityLocker.Value);
                        InOutPartsBox.AppendText("\r\n0");
                        InOutPartsBox.AppendText("\r\n" + LevelIndexLocker.Value);
                    }

                    CurrentWSG.NumberOfWeapons = CurrentWSG.NumberOfWeapons + 1;
                    CurrentWSG.WeaponStrings.Add(new List<string>());
                    CurrentWSG.WeaponValues.Add(new List<int>());


                    for (int Progress = 0; Progress < 14; Progress++)
                        CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1].Add(InOutPartsBox.Lines[Progress]);
                    for (int Progress = 0; Progress < 4; Progress++)
                        CurrentWSG.WeaponValues[CurrentWSG.NumberOfWeapons - 1].Add(Convert.ToInt32(InOutPartsBox.Lines[Progress + 14]));
                    TreeNode TempNode = new TreeNode();
                    TempNode.Text = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[CurrentWSG.NumberOfWeapons - 1]);
                    WeaponTree.Nodes.Add(TempNode);
                    //DoWeaponTree();
                }
                else if (ItemTypeLocker.SelectedIndex == 1)
                {
                    InOutPartsBox.Clear();

                    for (int Progress = 0; Progress < 9; Progress++)
                    {
                        if (Progress > 0) InOutPartsBox.AppendText("\r\n");
                        InOutPartsBox.AppendText((string)PartsLocker.Items[Progress]);
                    }
                    if (OverrideExportSettings.Checked == true)
                    {

                        if (RemAmmoOverride.Value == 0)
                            // Set quantity to 1 so noone gets hurt
                            InOutPartsBox.AppendText("\r\n1");
                        else
                            InOutPartsBox.AppendText("\r\n" + RemAmmoOverride.Value);

                        InOutPartsBox.AppendText("\r\n" + LevelIndexOverride.Value);
                        InOutPartsBox.AppendText("\r\n0");
                        InOutPartsBox.AppendText("\r\n" + QualityOverride.Value);
                    }
                    else
                    {
                        if (RemAmmoLocker.Value == 0)
                            // Set quantity to 1 so noone gets hurt
                            InOutPartsBox.AppendText("\r\n1");
                        else
                            InOutPartsBox.AppendText("\r\n" + RemAmmoLocker.Value);

                        InOutPartsBox.AppendText("\r\n" + QualityLocker.Value);
                        InOutPartsBox.AppendText("\r\n0");
                        InOutPartsBox.AppendText("\r\n" + LevelIndexLocker.Value);

                    }

                    List<string> itemstrings = new List<string>();
                    List<int> itemvalues = new List<int>();

                    for (int Progress = 0; Progress < 9; Progress++)
                        itemstrings.Add(InOutPartsBox.Lines[Progress]);
                    for (int Progress = 0; Progress < 4; Progress++)
                        itemvalues.Add(Convert.ToInt32(InOutPartsBox.Lines[Progress + 9]));

                    AddItem(LockerSelected, itemstrings, itemvalues);
                    ItemTree.Nodes.Add(LockerSelected);
                    //DoItemTree();
                }
            }
        }

        private void ItemTypeLocker_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (ItemTypeLocker.SelectedIndex == 0)
                for (int Progress = 9; Progress < 14; Progress++)
                {

                    PartsLocker.Items[Progress] = "None";
                }

            else if (ItemTypeLocker.SelectedIndex == 1)
                for (int Progress = 9; Progress < 14; Progress++)
                {

                    PartsLocker.Items[Progress] = "";
                }
        }

        private void ImportAllFromFileLocker_Click(object sender, EventArgs e)
        {
            OpenFileDialog tempRead = new OpenFileDialog();
            if (tempRead.ShowDialog() == DialogResult.OK)
            {
                try
                {

                    XmlTextReader reader = new XmlTextReader(OpenedLocker);
                    XmlDocument lockerxml = new XmlDocument();
                    lockerxml.Load(reader);
                    reader.Close();

                    reader = new XmlTextReader(tempRead.FileName);
                    XmlDocument importxml = new XmlDocument();
                    importxml.Load(reader);
                    reader.Close();

                    XmlNode lockerroot = lockerxml.DocumentElement;
                    XmlNode inputroot = importxml.DocumentElement;

                    lockerroot.InnerXml = lockerroot.InnerXml + inputroot.InnerXml;
                    lockerxml.Save(OpenedLocker);

                    XmlLocker.Reload();

                    DoLockerTreeNodupe(OpenedLocker);
                    DoLockerTree(OpenedLocker);
                }
                catch
                {
                    MessageBox.Show("Import failed.");
                }
            }
        }

        private void ImportAllFromItemsLocker_Click(object sender, EventArgs e)
        {
            for (int Progress = 0; Progress < CurrentWSG.NumberOfItems; Progress++)
            {
                string ItemName = GetItemNameAdvanced(CurrentWSG.ItemStrings[Progress]);
                string UniqueName = XmlLocker.GetUniqueName(ItemName);
                XmlLocker.AddItem(UniqueName, "Item", CurrentWSG.ItemStrings[Progress], CurrentWSG.ItemValues[Progress]);

                TreeNode temp = new TreeNode();
                temp.Text = UniqueName;
                LockerTree.Nodes.Add(temp);
            }
            DoLockerTree(OpenedLocker);
        }

        private void ImportAllFromWeaponsLocker_Click(object sender, EventArgs e)
        {
            for (int Progress = 0; Progress < CurrentWSG.NumberOfWeapons; Progress++)
            {
                string ItemName = GetWeaponNameAdvanced(CurrentWSG.WeaponStrings[Progress]);
                //                string ItemName = GetLongName(TitlesXml, CurrentWSG.WeaponStrings[Progress][0], CurrentWSG.WeaponStrings[Progress][12], CurrentWSG.WeaponStrings[Progress][13]);
                string UniqueName = XmlLocker.GetUniqueName(ItemName);
                XmlLocker.AddItem(UniqueName, "Weapon", CurrentWSG.WeaponStrings[Progress], CurrentWSG.WeaponValues[Progress]);

                TreeNode temp = new TreeNode();
                temp.Text = UniqueName;
                LockerTree.Nodes.Add(temp);

                XmlLocker.Reload();
            }
            DoLockerTree(OpenedLocker);
        }

        private void ImportFromTextLocker(string Text)
        {
            InOutPartsBox.Clear();
            InOutPartsBox.Text = Text;
            InOutPartsBox.Text.Replace(" ", "");

            int Progress;
            int tempValue;

            NameLocker.Text = "";

            for (Progress = 0; Progress < 14; Progress++)
            {
                if (int.TryParse(InOutPartsBox.Lines[Progress], out tempValue))
                    break;  // Get out after the first int value

                PartsLocker.Items[Progress] = InOutPartsBox.Lines[Progress]; 
            }

            if (Progress == 9) 
            {
                ItemTypeLocker.SelectedIndex = 1;
                NameLocker.Text = GetItemNameAdvanced(InOutPartsBox.Lines);
            }
            else if (Progress == 14)
            {
                ItemTypeLocker.SelectedIndex = 0;
                NameLocker.Text = GetWeaponNameAdvanced(InOutPartsBox.Lines);
            }
            else
                throw new System.FormatException(); // exception if the format isn't righr for either weapon or item

            // Exception if any of these are not int values
            RemAmmoLocker.Value = Convert.ToInt32(InOutPartsBox.Lines[Progress++]);
            QualityLocker.Value = Convert.ToInt32(InOutPartsBox.Lines[Progress++]);
            Progress++;  // Just skip the equipped slot since items in the locker aren't equipped
            LevelIndexLocker.Value = Convert.ToInt32(InOutPartsBox.Lines[Progress++]);
        }

        private void ImportFromClipboardLocker_Click(object sender, EventArgs e)
        {
            try
            {
                ImportFromTextLocker(Clipboard.GetText());
            }
            catch
            {
                MessageBox.Show("Invalid clipboard data.  Reverting to saved values.");
                LockerTree_AfterNodeSelect(null, null);  // reloads the saved values from the node
            }
        }            

        private void ImportFromFileLocker_Click(object sender, EventArgs e)
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.txt";
            FromFile.Filter = "Item Files(*.txt)|*.txt";

            FromFile.FileName = WeaponPartsGroup.Text + ".txt";
            if (FromFile.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ImportFromTextLocker(System.IO.File.ReadAllText(FromFile.FileName));
                }
                catch
                {
                    MessageBox.Show("Invalid file data.  Reverting to saved values.");
                    LockerTree_AfterNodeSelect(null, null);  // reloads the saved values from the node
                }
            }
        }

        private void lockerSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnlockerSearch_Click(this, KeyEventArgs.Empty);
            }
        }

        private void LockerTree_AfterNodeSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                PartsLocker.Items.Clear();
                XmlLocker.path = OpenedLocker;

                //Ini.IniFile Locker = new Ini.IniFile(OpenedLocker);
                //int Lockerindex = Convert.ToInt32(LockerTree.SelectedNode.TagString);
                if (LockerTree.SelectedNode.FirstNode == null)
                {
                    string SelectedItem = LockerTree.SelectedNode.Name;

                    NameLocker.Text = SelectedItem;

                    RatingLocker.Text = XmlLocker.XmlReadValue(SelectedItem, "Rating");
                    DescriptionLocker.Text = XmlLocker.XmlReadValue(SelectedItem, "Description");
                    DescriptionLocker.Text = DescriptionLocker.Text.Replace("$LINE$", "\r\n");
                    ItemTypeLocker.SelectedItem = XmlLocker.XmlReadValue(SelectedItem, "Type");

                    for (int Progress = 0; Progress < 14; Progress++)
                        PartsLocker.Items.Add(XmlLocker.XmlReadValue(SelectedItem, "Part" + (Progress + 1)));

                    try
                    {
                        RemAmmoLocker.Value = Convert.ToInt32(XmlLocker.XmlReadValue(SelectedItem, "RemAmmo_Quantity"));
                    }
                    catch
                    {
                        RemAmmoLocker.Value = 0;
                    }
                    try
                    {
                        QualityLocker.Value = Convert.ToInt32(XmlLocker.XmlReadValue(SelectedItem, "Quality"));
                    }
                    catch
                    {
                        QualityLocker.Value = 0;
                    }
                    try
                    {
                        LevelIndexLocker.Value = Convert.ToInt32(XmlLocker.XmlReadValue(SelectedItem, "Level"));
                    }
                    catch
                    {
                        LevelIndexLocker.Value = 0;
                    }


                    /*                int Lockerindex = LockerTree.SelectedNode.Index;

                                    NameLocker.Text = XmlLocker.ListSectionNames()[Lockerindex];

                                    RatingLocker.Rating = Convert.ToInt32(XmlLocker.XmlReadValue(XmlLocker.ListSectionNames()[Lockerindex], "Rating"));
                                    DescriptionLocker.Text = XmlLocker.XmlReadValue(XmlLocker.ListSectionNames()[Lockerindex], "Description");
                                    DescriptionLocker.Text = DescriptionLocker.Text.Replace("$LINE$", "\r\n");
                                    ItemTypeLocker.SelectedItem = XmlLocker.XmlReadValue(XmlLocker.ListSectionNames()[Lockerindex], "Type");

                                    for (int Progress = 0; Progress < 14; Progress++)
                                        PartsLocker.Items.Add(XmlLocker.XmlReadValue(XmlLocker.ListSectionNames()[Lockerindex], "Part" + (Progress + 1)));
                    */

                }
            }
            catch { }
        }

        private void NewItemLocker_Click(object sender, EventArgs e)
        {

            List<string> iniListSectionNames = new List<string>();
            iniListSectionNames = XmlLocker.stListSectionNames();
            iniListSectionNames.TrimExcess();

            // Ok all Lockeritems now in a list

            int Occurances = 0;
            List<string> itemparts = new List<string> { "None", "None", "None", "None", "None", "None", "None", "None", "None" };
            List<int> itemvalues = new List<int> { 0, 5, 0, 63 };

            // Search the WeaponTree.Nodes[Progress].Text in the locker
            if (iniListSectionNames.Contains("New Item"))
            {
                // rename and try again until in can be added
                do
                {
                    Occurances++;
                } while (iniListSectionNames.Contains("New Item" + " (Copy " + Occurances + ")"));
                //More than one found

                //Add new Item to the xml locker
                XmlLocker.AddItem("New Item" + " (Copy " + Occurances + ")", "Weapon", itemparts, itemvalues);

                TreeNode temp = new TreeNode();
                temp.Text = "New Item" + " (Copy " + Occurances + ")";
                temp.Name = "New Item" + " (Copy " + Occurances + ")";
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text + " (Copy " + Occurances + ")");
            }
            else
            {
                //only one found
                XmlLocker.AddItem("New Item", "Weapon", itemparts, itemvalues);

                XmlLocker.Reload(); // Reload the locker next time

                TreeNode temp = new TreeNode();
                temp.Text = "New Item";
                temp.Name = "New Item";
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text);
            }

        }

        private void NewWeaponLocker_Click(object sender, EventArgs e)
        {
            List<string> iniListSectionNames = new List<string>();
            iniListSectionNames = XmlLocker.stListSectionNames();
            iniListSectionNames.TrimExcess();

            // Ok all Lockeritems now in a list

            int Occurances = 0;
            List<string> itemparts = new List<string> { "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None", "None" };
            List<int> itemvalues = new List<int> { 0, 5, 0, 63 };

            // Search the WeaponTree.Nodes[Progress].Text in the locker
            if (iniListSectionNames.Contains("New Weapon"))
            {
                // rename and try again until in can be added
                do
                {
                    Occurances++;
                } while (iniListSectionNames.Contains("New Weapon" + " (Copy " + Occurances + ")"));
                //More than one found

                //Add new Item to the xml locker
                XmlLocker.AddItem("New Weapon" + " (Copy " + Occurances + ")", "Weapon", itemparts, itemvalues);

                TreeNode temp = new TreeNode();
                temp.Text = "New Weapon" + " (Copy " + Occurances + ")";
                temp.Name = "New Weapon" + " (Copy " + Occurances + ")";
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text + " (Copy " + Occurances + ")");
            }
            else
            {
                //only one found
                XmlLocker.AddItem("New Weapon", "Weapon", itemparts, itemvalues);

                XmlLocker.Reload(); // Reload the locker next time

                TreeNode temp = new TreeNode();
                temp.Text = "New Weapon";
                temp.Name = "New Weapon";
                LockerTree.Nodes.Add(temp);

                //iniListSectionNames.Add(WeaponTree.Nodes[Progress].Text);
            }


        }

        private void OpenLocker_Click(object sender, EventArgs e)
        {
            OpenFileDialog FromFile = new OpenFileDialog();
            FromFile.DefaultExt = "*.wtl";
            FromFile.Filter = "WillowTree Locker(*.xml;*.wtl)|*.xml;*.wtl";

            FromFile.FileName = WeaponPartsGroup.Text + ".xml";
            try
            {
                if (FromFile.ShowDialog() == DialogResult.OK)
                {
                    OpenedLocker = FromFile.FileName;
                    if (FromFile.FileName.EndsWith("wtl"))
                    {
                        //Convert wtl to xml
                        DoLockerTreetry(FromFile.FileName);
                        DoLockerTree(FromFile.FileName.Replace(".wtl", ".xml"));
                    } 
                    else if (FromFile.FileName.EndsWith("xml"))
                    {
                        XmlLocker.Reload(FromFile.FileName);
                        DoLockerTreeNodupe(FromFile.FileName);
                        DoLockerTree(FromFile.FileName);
                        
                    }
                }
            }
            catch { MessageBox.Show("Could not load the selected WillowTree Locker."); }
        }

        private void SaveAsLocker_Click(object sender, EventArgs e)
        {
            SaveFileDialog ToFile = new SaveFileDialog();
            ToFile.DefaultExt = "*.xml";
            ToFile.Filter = "WillowTree Locker(*.xml)|*.xml";

            ToFile.FileName = "default.xml";
            try
            {
                if (ToFile.ShowDialog() == DialogResult.OK)
                {
                    File.Copy(OpenedLocker, ToFile.FileName, true);
                    DoLockerTree(ToFile.FileName);
                }
            }
            catch { MessageBox.Show("Could not save the selected WillowTree Locker."); }
        }

        public void SaveChangesToLocker()
        {
            // no dupes in locker

            // Locate Node

            try
            {
                string Description = "";
                string LockerSelectedNode = LockerTree.SelectedNode.Name;

                //XmlLocker.ListSectionNames()[LockerTree.SelectedNode.Index] = NameLocker.Text;
                XmlLocker.XmlWriteValue(LockerSelectedNode, "Rating", "" + RatingLocker.Text);
                for (int Progress = 0; Progress < DescriptionLocker.Lines.Length; Progress++)
                    Description = Description + DescriptionLocker.Lines[Progress] + "$LINE$";
                for (int Progress = 0; Progress < 14; Progress++)
                    XmlLocker.XmlWriteValue(LockerSelectedNode, "Part" + (Progress + 1), (string)PartsLocker.Items[Progress]);

                XmlLocker.XmlWriteValue(LockerSelectedNode, "Description", Description);
                XmlLocker.XmlWriteValue(LockerSelectedNode, "Type", "" + ItemTypeLocker.SelectedItem);

                XmlLocker.XmlWriteValue(LockerSelectedNode, "RemAmmo_Quantity", RemAmmoLocker.Value.ToString());
                XmlLocker.XmlWriteValue(LockerSelectedNode, "Quality", QualityLocker.Value.ToString());
                XmlLocker.XmlWriteValue(LockerSelectedNode, "Level", LevelIndexLocker.Value.ToString());

                //Locker.IniReadValue(Locker.ListSectionNames()[LockerTree.SelectedNode.Index] = "";

                //DoLockerTree(OpenedLocker);
                //LockerTree.SelectedNode.Text = XmlLocker.ListSectionNames()[LockerTree.SelectedNode.Index];

                if (LockerSelectedNode != NameLocker.Text)
                {
                    string UniqueName = XmlLocker.GetUniqueName(NameLocker.Text);
                    XmlLocker.RenameItem(LockerSelectedNode, UniqueName);
                    LockerTree.SelectedNode.Name = UniqueName;
                    LockerTree.SelectedNode.Text = UniqueName;
                    LockerTree.Update();
                }

                //              NameLocker.Text = LockerSelectedNode;

                XmlLocker.Reload(); //reload next time
            }
            catch { MessageBox.Show("Couldn't save changes."); }
        }

        private void SaveChangesLocker_Click(object sender, EventArgs e)
        {
            SaveChangesToLocker();
        }

        #endregion
        #region <<<<< DEBUG PANEL >>>>>

        private void Breakpoint_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Debugger.Break();
        }

        private void button1_Click(object sender, EventArgs e)
        {
        }

        #endregion
    }
}

